aboutsummaryrefslogtreecommitdiff
path: root/deps/v8/test/unittests/interpreter/bytecode-array-builder-unittest.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/test/unittests/interpreter/bytecode-array-builder-unittest.cc')
-rw-r--r--deps/v8/test/unittests/interpreter/bytecode-array-builder-unittest.cc261
1 files changed, 123 insertions, 138 deletions
diff --git a/deps/v8/test/unittests/interpreter/bytecode-array-builder-unittest.cc b/deps/v8/test/unittests/interpreter/bytecode-array-builder-unittest.cc
index 30202c9d72..2140aa83c7 100644
--- a/deps/v8/test/unittests/interpreter/bytecode-array-builder-unittest.cc
+++ b/deps/v8/test/unittests/interpreter/bytecode-array-builder-unittest.cc
@@ -6,6 +6,7 @@
#include "src/interpreter/bytecode-array-builder.h"
#include "src/interpreter/bytecode-array-iterator.h"
+#include "src/interpreter/bytecode-register-allocator.h"
#include "test/unittests/test-utils.h"
namespace v8 {
@@ -22,12 +23,12 @@ class BytecodeArrayBuilderTest : public TestWithIsolateAndZone {
TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
BytecodeArrayBuilder builder(isolate(), zone());
- builder.set_locals_count(1);
+ builder.set_locals_count(200);
builder.set_context_count(1);
builder.set_parameter_count(0);
- CHECK_EQ(builder.locals_count(), 1);
+ CHECK_EQ(builder.locals_count(), 200);
CHECK_EQ(builder.context_count(), 1);
- CHECK_EQ(builder.fixed_register_count(), 2);
+ CHECK_EQ(builder.fixed_register_count(), 201);
// Emit constant loads.
builder.LoadLiteral(Smi::FromInt(0))
@@ -39,68 +40,77 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
.LoadTrue()
.LoadFalse();
- // Emit accumulator transfers.
+ // Emit accumulator transfers. Stores followed by loads to the same register
+ // are not generated. Hence, a dummy instruction in between.
Register reg(0);
- builder.LoadAccumulatorWithRegister(reg).StoreAccumulatorInRegister(reg);
+ builder.LoadAccumulatorWithRegister(reg)
+ .LoadNull()
+ .StoreAccumulatorInRegister(reg);
- // Emit global load / store operations.
- builder.LoadGlobal(0, 1, LanguageMode::SLOPPY, TypeofMode::NOT_INSIDE_TYPEOF)
- .LoadGlobal(0, 1, LanguageMode::STRICT, TypeofMode::NOT_INSIDE_TYPEOF)
- .LoadGlobal(0, 1, LanguageMode::SLOPPY, TypeofMode::INSIDE_TYPEOF)
- .LoadGlobal(0, 1, LanguageMode::STRICT, TypeofMode::INSIDE_TYPEOF)
- .StoreGlobal(0, 1, LanguageMode::SLOPPY)
- .StoreGlobal(0, 1, LanguageMode::STRICT);
+ // Emit register-register transfer.
+ Register other(1);
+ builder.MoveRegister(reg, other);
- // Emit wide global load / store operations.
- builder.LoadGlobal(0, 1024, LanguageMode::SLOPPY,
+ // Emit register-register exchanges.
+ Register wide(150);
+ builder.ExchangeRegisters(reg, wide);
+ builder.ExchangeRegisters(wide, reg);
+ Register wider(151);
+ builder.ExchangeRegisters(wide, wider);
+
+ // Emit global load / store operations.
+ Factory* factory = isolate()->factory();
+ Handle<String> name = factory->NewStringFromStaticChars("var_name");
+ builder.LoadGlobal(name, 1, LanguageMode::SLOPPY,
TypeofMode::NOT_INSIDE_TYPEOF)
- .LoadGlobal(1024, 1, LanguageMode::STRICT, TypeofMode::NOT_INSIDE_TYPEOF)
- .LoadGlobal(0, 1024, LanguageMode::SLOPPY, TypeofMode::INSIDE_TYPEOF)
- .LoadGlobal(1024, 1, LanguageMode::STRICT, TypeofMode::INSIDE_TYPEOF)
- .StoreGlobal(0, 1024, LanguageMode::SLOPPY)
- .StoreGlobal(1024, 1, LanguageMode::STRICT);
+ .LoadGlobal(name, 1, LanguageMode::STRICT, TypeofMode::NOT_INSIDE_TYPEOF)
+ .LoadGlobal(name, 1, LanguageMode::SLOPPY, TypeofMode::INSIDE_TYPEOF)
+ .LoadGlobal(name, 1, LanguageMode::STRICT, TypeofMode::INSIDE_TYPEOF)
+ .StoreGlobal(name, 1, LanguageMode::SLOPPY)
+ .StoreGlobal(name, 1, LanguageMode::STRICT);
// Emit context operations.
- builder.PushContext(reg);
- builder.PopContext(reg);
- builder.LoadContextSlot(reg, 1);
- builder.StoreContextSlot(reg, 1);
+ builder.PushContext(reg)
+ .PopContext(reg)
+ .LoadContextSlot(reg, 1)
+ .StoreContextSlot(reg, 1);
// Emit load / store property operations.
- builder.LoadNamedProperty(reg, 0, 0, LanguageMode::SLOPPY)
+ builder.LoadNamedProperty(reg, name, 0, LanguageMode::SLOPPY)
.LoadKeyedProperty(reg, 0, LanguageMode::SLOPPY)
- .StoreNamedProperty(reg, 0, 0, LanguageMode::SLOPPY)
+ .StoreNamedProperty(reg, name, 0, LanguageMode::SLOPPY)
.StoreKeyedProperty(reg, reg, 0, LanguageMode::SLOPPY)
- .LoadNamedProperty(reg, 0, 0, LanguageMode::STRICT)
+ .LoadNamedProperty(reg, name, 0, LanguageMode::STRICT)
.LoadKeyedProperty(reg, 0, LanguageMode::STRICT)
- .StoreNamedProperty(reg, 0, 0, LanguageMode::STRICT)
+ .StoreNamedProperty(reg, name, 0, LanguageMode::STRICT)
.StoreKeyedProperty(reg, reg, 0, LanguageMode::STRICT);
- // Emit wide load / store property operations.
- builder.LoadNamedProperty(reg, 2056, 0, LanguageMode::SLOPPY)
- .LoadKeyedProperty(reg, 2056, LanguageMode::SLOPPY)
- .StoreNamedProperty(reg, 0, 2056, LanguageMode::SLOPPY)
- .StoreKeyedProperty(reg, reg, 2056, LanguageMode::SLOPPY)
- .LoadNamedProperty(reg, 2056, 0, LanguageMode::STRICT)
- .LoadKeyedProperty(reg, 2056, LanguageMode::STRICT)
- .StoreNamedProperty(reg, 0, 2056, LanguageMode::STRICT)
- .StoreKeyedProperty(reg, reg, 2056, LanguageMode::STRICT);
+ // Emit load / store lookup slots.
+ builder.LoadLookupSlot(name, TypeofMode::NOT_INSIDE_TYPEOF)
+ .LoadLookupSlot(name, TypeofMode::INSIDE_TYPEOF)
+ .StoreLookupSlot(name, LanguageMode::SLOPPY)
+ .StoreLookupSlot(name, LanguageMode::STRICT);
// Emit closure operations.
- builder.CreateClosure(NOT_TENURED);
+ Handle<SharedFunctionInfo> shared_info = factory->NewSharedFunctionInfo(
+ factory->NewStringFromStaticChars("function_a"), MaybeHandle<Code>(),
+ false);
+ builder.CreateClosure(shared_info, NOT_TENURED);
// Emit argument creation operations.
builder.CreateArguments(CreateArgumentsType::kMappedArguments)
.CreateArguments(CreateArgumentsType::kUnmappedArguments);
- // Emit literal creation operations
- builder.CreateRegExpLiteral(0, reg)
- .CreateArrayLiteral(0, 0)
- .CreateObjectLiteral(0, 0);
+ // Emit literal creation operations.
+ builder.CreateRegExpLiteral(factory->NewStringFromStaticChars("a"), 0, 0)
+ .CreateArrayLiteral(factory->NewFixedArray(1), 0, 0)
+ .CreateObjectLiteral(factory->NewFixedArray(1), 0, 0);
// Call operations.
- builder.Call(reg, reg, 0)
+ builder.Call(reg, reg, 0, 0)
+ .Call(reg, reg, 0, 1024)
.CallRuntime(Runtime::kIsArray, reg, 1)
+ .CallRuntimeForPair(Runtime::kLoadLookupSlot, reg, 1, reg)
.CallJSRuntime(Context::SPREAD_ITERABLE_INDEX, reg, 1);
// Emit binary operator invocations.
@@ -128,7 +138,9 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
builder.LogicalNot().TypeOf();
// Emit delete
- builder.Delete(reg, LanguageMode::SLOPPY).Delete(reg, LanguageMode::STRICT);
+ builder.Delete(reg, LanguageMode::SLOPPY)
+ .Delete(reg, LanguageMode::STRICT)
+ .DeleteLookupSlot();
// Emit new.
builder.New(reg, reg, 0);
@@ -147,7 +159,6 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
// Emit cast operator invocations.
builder.CastAccumulatorToNumber()
- .CastAccumulatorToBoolean()
.CastAccumulatorToJSObject()
.CastAccumulatorToName();
@@ -198,14 +209,75 @@ TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) {
.Throw()
.Bind(&after_throw);
- builder.ForInPrepare(reg).ForInDone(reg).ForInNext(reg, reg);
+ builder.ForInPrepare(reg, reg, reg)
+ .ForInDone(reg, reg)
+ .ForInNext(reg, reg, reg, reg)
+ .ForInStep(reg);
// Wide constant pool loads
for (int i = 0; i < 256; i++) {
// Emit junk in constant pool to force wide constant pool index.
- builder.GetConstantPoolEntry(handle(Smi::FromInt(i), isolate()));
+ builder.LoadLiteral(factory->NewNumber(2.5321 + i));
}
builder.LoadLiteral(Smi::FromInt(20000000));
+ Handle<String> wide_name = factory->NewStringFromStaticChars("var_wide_name");
+
+ // Emit wide global load / store operations.
+ builder.LoadGlobal(name, 1024, LanguageMode::SLOPPY,
+ TypeofMode::NOT_INSIDE_TYPEOF)
+ .LoadGlobal(wide_name, 1, LanguageMode::STRICT,
+ TypeofMode::NOT_INSIDE_TYPEOF)
+ .LoadGlobal(name, 1024, LanguageMode::SLOPPY, TypeofMode::INSIDE_TYPEOF)
+ .LoadGlobal(wide_name, 1, LanguageMode::STRICT, TypeofMode::INSIDE_TYPEOF)
+ .StoreGlobal(name, 1024, LanguageMode::SLOPPY)
+ .StoreGlobal(wide_name, 1, LanguageMode::STRICT);
+
+ // Emit wide load / store property operations.
+ builder.LoadNamedProperty(reg, wide_name, 0, LanguageMode::SLOPPY)
+ .LoadKeyedProperty(reg, 2056, LanguageMode::SLOPPY)
+ .StoreNamedProperty(reg, wide_name, 0, LanguageMode::SLOPPY)
+ .StoreKeyedProperty(reg, reg, 2056, LanguageMode::SLOPPY)
+ .LoadNamedProperty(reg, wide_name, 0, LanguageMode::STRICT)
+ .LoadKeyedProperty(reg, 2056, LanguageMode::STRICT)
+ .StoreNamedProperty(reg, wide_name, 0, LanguageMode::STRICT)
+ .StoreKeyedProperty(reg, reg, 2056, LanguageMode::STRICT);
+
+ // Emit wide context operations.
+ builder.LoadContextSlot(reg, 1024)
+ .StoreContextSlot(reg, 1024);
+
+ // Emit wide load / store lookup slots.
+ builder.LoadLookupSlot(wide_name, TypeofMode::NOT_INSIDE_TYPEOF)
+ .LoadLookupSlot(wide_name, TypeofMode::INSIDE_TYPEOF)
+ .StoreLookupSlot(wide_name, LanguageMode::SLOPPY)
+ .StoreLookupSlot(wide_name, LanguageMode::STRICT);
+
+ // CreateClosureWide
+ Handle<SharedFunctionInfo> shared_info2 = factory->NewSharedFunctionInfo(
+ factory->NewStringFromStaticChars("function_b"), MaybeHandle<Code>(),
+ false);
+ builder.CreateClosure(shared_info2, NOT_TENURED);
+
+ // Emit wide variant of literal creation operations.
+ builder.CreateRegExpLiteral(factory->NewStringFromStaticChars("wide_literal"),
+ 0, 0)
+ .CreateArrayLiteral(factory->NewFixedArray(2), 0, 0)
+ .CreateObjectLiteral(factory->NewFixedArray(2), 0, 0);
+
+ // Longer jumps requiring ConstantWide operand
+ builder.Jump(&start).JumpIfNull(&start).JumpIfUndefined(&start);
+ // Perform an operation that returns boolean value to
+ // generate JumpIfTrue/False
+ builder.CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
+ .JumpIfTrue(&start)
+ .CompareOperation(Token::Value::EQ, reg, Strength::WEAK)
+ .JumpIfFalse(&start);
+ // Perform an operation that returns a non-boolean operation to
+ // generate JumpIfToBooleanTrue/False.
+ builder.BinaryOperation(Token::Value::ADD, reg, Strength::WEAK)
+ .JumpIfTrue(&start)
+ .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK)
+ .JumpIfFalse(&start);
builder.Return();
@@ -246,7 +318,7 @@ TEST_F(BytecodeArrayBuilderTest, FrameSizesLookGood) {
builder.set_locals_count(locals);
builder.set_context_count(contexts);
- TemporaryRegisterScope temporaries(&builder);
+ BytecodeRegisterAllocator temporaries(&builder);
for (int i = 0; i < temps; i++) {
builder.StoreAccumulatorInRegister(temporaries.NewRegister());
}
@@ -261,32 +333,6 @@ TEST_F(BytecodeArrayBuilderTest, FrameSizesLookGood) {
}
-TEST_F(BytecodeArrayBuilderTest, TemporariesRecycled) {
- BytecodeArrayBuilder builder(isolate(), zone());
- builder.set_parameter_count(0);
- builder.set_locals_count(0);
- builder.set_context_count(0);
- builder.Return();
-
- int first;
- {
- TemporaryRegisterScope temporaries(&builder);
- first = temporaries.NewRegister().index();
- temporaries.NewRegister();
- temporaries.NewRegister();
- temporaries.NewRegister();
- }
-
- int second;
- {
- TemporaryRegisterScope temporaries(&builder);
- second = temporaries.NewRegister().index();
- }
-
- CHECK_EQ(first, second);
-}
-
-
TEST_F(BytecodeArrayBuilderTest, RegisterValues) {
int index = 1;
uint8_t operand = static_cast<uint8_t>(-index);
@@ -320,15 +366,15 @@ TEST_F(BytecodeArrayBuilderTest, RegisterType) {
builder.set_locals_count(3);
builder.set_context_count(0);
- TemporaryRegisterScope temporary_register_scope(&builder);
- Register temp0 = temporary_register_scope.NewRegister();
+ BytecodeRegisterAllocator register_allocator(&builder);
+ Register temp0 = register_allocator.NewRegister();
Register param0(builder.Parameter(0));
Register param9(builder.Parameter(9));
- Register temp1 = temporary_register_scope.NewRegister();
+ Register temp1 = register_allocator.NewRegister();
Register reg0(0);
Register reg1(1);
Register reg2(2);
- Register temp2 = temporary_register_scope.NewRegister();
+ Register temp2 = register_allocator.NewRegister();
CHECK_EQ(builder.RegisterIsParameterOrLocal(temp0), false);
CHECK_EQ(builder.RegisterIsParameterOrLocal(temp1), false);
CHECK_EQ(builder.RegisterIsParameterOrLocal(temp2), false);
@@ -641,67 +687,6 @@ TEST_F(BytecodeArrayBuilderTest, LabelAddressReuse) {
}
-TEST_F(BytecodeArrayBuilderTest, ToBoolean) {
- BytecodeArrayBuilder builder(isolate(), zone());
- builder.set_parameter_count(0);
- builder.set_locals_count(0);
- builder.set_context_count(0);
-
- // Check ToBoolean emitted at start of a basic block.
- builder.CastAccumulatorToBoolean();
-
- // Check ToBoolean emitted preceding bytecode is non-boolean.
- builder.LoadNull().CastAccumulatorToBoolean();
-
- // Check ToBoolean omitted if preceding bytecode is boolean.
- builder.LoadFalse().CastAccumulatorToBoolean();
-
- // Check ToBoolean emitted if it is at the start of a basic block caused by a
- // bound label.
- BytecodeLabel label;
- builder.LoadFalse()
- .Bind(&label)
- .CastAccumulatorToBoolean();
-
- // Check ToBoolean emitted if it is at the start of a basic block caused by a
- // jump.
- builder.LoadFalse()
- .JumpIfTrue(&label)
- .CastAccumulatorToBoolean();
-
- builder.Return();
-
- Handle<BytecodeArray> array = builder.ToBytecodeArray();
- BytecodeArrayIterator iterator(array);
- CHECK_EQ(iterator.current_bytecode(), Bytecode::kToBoolean);
- iterator.Advance();
-
- CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaNull);
- iterator.Advance();
- CHECK_EQ(iterator.current_bytecode(), Bytecode::kToBoolean);
- iterator.Advance();
-
- CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaFalse);
- iterator.Advance();
-
- CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaFalse);
- iterator.Advance();
- CHECK_EQ(iterator.current_bytecode(), Bytecode::kToBoolean);
- iterator.Advance();
-
- CHECK_EQ(iterator.current_bytecode(), Bytecode::kLdaFalse);
- iterator.Advance();
- CHECK_EQ(iterator.current_bytecode(), Bytecode::kJumpIfTrue);
- iterator.Advance();
- CHECK_EQ(iterator.current_bytecode(), Bytecode::kToBoolean);
- iterator.Advance();
-
- CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn);
- iterator.Advance();
- CHECK(iterator.done());
-}
-
-
} // namespace interpreter
} // namespace internal
} // namespace v8