| OLD | NEW |
| 1 // Copyright 2014 the V8 project authors. All rights reserved. | 1 // Copyright 2014 the V8 project authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "src/v8.h" | 5 #include "src/v8.h" |
| 6 | 6 |
| 7 #include "src/interpreter/bytecode-array-builder.h" | 7 #include "src/interpreter/bytecode-array-builder.h" |
| 8 #include "src/interpreter/bytecode-array-iterator.h" | 8 #include "src/interpreter/bytecode-array-iterator.h" |
| 9 #include "src/interpreter/bytecode-register-allocator.h" | 9 #include "src/interpreter/bytecode-register-allocator.h" |
| 10 #include "test/unittests/test-utils.h" | 10 #include "test/unittests/test-utils.h" |
| 11 | 11 |
| 12 namespace v8 { | 12 namespace v8 { |
| 13 namespace internal { | 13 namespace internal { |
| 14 namespace interpreter { | 14 namespace interpreter { |
| 15 | 15 |
| 16 class BytecodeArrayBuilderTest : public TestWithIsolateAndZone { | 16 class BytecodeArrayBuilderTest : public TestWithIsolateAndZone { |
| 17 public: | 17 public: |
| 18 BytecodeArrayBuilderTest() {} | 18 BytecodeArrayBuilderTest() {} |
| 19 ~BytecodeArrayBuilderTest() override {} | 19 ~BytecodeArrayBuilderTest() override {} |
| 20 }; | 20 }; |
| 21 | 21 |
| 22 | 22 |
| 23 TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) { | 23 TEST_F(BytecodeArrayBuilderTest, AllBytecodesGenerated) { |
| 24 BytecodeArrayBuilder builder(isolate(), zone()); | 24 BytecodeArrayBuilder builder(isolate(), zone()); |
| 25 | 25 |
| 26 builder.set_locals_count(200); | 26 builder.set_locals_count(131); |
| 27 builder.set_context_count(1); | 27 builder.set_context_count(1); |
| 28 builder.set_parameter_count(0); | 28 builder.set_parameter_count(0); |
| 29 CHECK_EQ(builder.locals_count(), 200); | 29 CHECK_EQ(builder.locals_count(), 131); |
| 30 CHECK_EQ(builder.context_count(), 1); | 30 CHECK_EQ(builder.context_count(), 1); |
| 31 CHECK_EQ(builder.fixed_register_count(), 201); | 31 CHECK_EQ(builder.fixed_register_count(), 132); |
| 32 | 32 |
| 33 // Emit constant loads. | 33 // Emit constant loads. |
| 34 builder.LoadLiteral(Smi::FromInt(0)) | 34 builder.LoadLiteral(Smi::FromInt(0)) |
| 35 .LoadLiteral(Smi::FromInt(8)) | 35 .LoadLiteral(Smi::FromInt(8)) |
| 36 .LoadLiteral(Smi::FromInt(10000000)) | 36 .LoadLiteral(Smi::FromInt(10000000)) |
| 37 .LoadUndefined() | 37 .LoadUndefined() |
| 38 .LoadNull() | 38 .LoadNull() |
| 39 .LoadTheHole() | 39 .LoadTheHole() |
| 40 .LoadTrue() | 40 .LoadTrue() |
| 41 .LoadFalse(); | 41 .LoadFalse(); |
| 42 | 42 |
| 43 // Emit accumulator transfers. Stores followed by loads to the same register | |
| 44 // are not generated. Hence, a dummy instruction in between. | |
| 45 Register reg(0); | 43 Register reg(0); |
| 44 Register other(reg.index() + 1); |
| 45 Register wide(128); |
| 46 |
| 46 builder.LoadAccumulatorWithRegister(reg) | 47 builder.LoadAccumulatorWithRegister(reg) |
| 47 .LoadNull() | 48 .LoadNull() |
| 48 .StoreAccumulatorInRegister(reg); | 49 .StoreAccumulatorInRegister(reg); |
| 49 | 50 |
| 50 // Emit register-register transfer. | 51 // Emit register-register transfer. |
| 51 Register other(1); | |
| 52 builder.MoveRegister(reg, other); | 52 builder.MoveRegister(reg, other); |
| 53 | 53 builder.MoveRegister(reg, wide); |
| 54 // Emit register-register exchanges. | |
| 55 Register wide(150); | |
| 56 builder.ExchangeRegisters(reg, wide); | |
| 57 builder.ExchangeRegisters(wide, reg); | |
| 58 Register wider(151); | |
| 59 builder.ExchangeRegisters(wide, wider); | |
| 60 | 54 |
| 61 // Emit global load / store operations. | 55 // Emit global load / store operations. |
| 62 Factory* factory = isolate()->factory(); | 56 Factory* factory = isolate()->factory(); |
| 63 Handle<String> name = factory->NewStringFromStaticChars("var_name"); | 57 Handle<String> name = factory->NewStringFromStaticChars("var_name"); |
| 64 builder.LoadGlobal(name, 1, LanguageMode::SLOPPY, | 58 builder.LoadGlobal(name, 1, LanguageMode::SLOPPY, |
| 65 TypeofMode::NOT_INSIDE_TYPEOF) | 59 TypeofMode::NOT_INSIDE_TYPEOF) |
| 66 .LoadGlobal(name, 1, LanguageMode::STRICT, TypeofMode::NOT_INSIDE_TYPEOF) | 60 .LoadGlobal(name, 1, LanguageMode::STRICT, TypeofMode::NOT_INSIDE_TYPEOF) |
| 67 .LoadGlobal(name, 1, LanguageMode::SLOPPY, TypeofMode::INSIDE_TYPEOF) | 61 .LoadGlobal(name, 1, LanguageMode::SLOPPY, TypeofMode::INSIDE_TYPEOF) |
| 68 .LoadGlobal(name, 1, LanguageMode::STRICT, TypeofMode::INSIDE_TYPEOF) | 62 .LoadGlobal(name, 1, LanguageMode::STRICT, TypeofMode::INSIDE_TYPEOF) |
| 69 .StoreGlobal(name, 1, LanguageMode::SLOPPY) | 63 .StoreGlobal(name, 1, LanguageMode::SLOPPY) |
| (...skipping 30 matching lines...) Expand all Loading... |
| 100 // Emit argument creation operations. | 94 // Emit argument creation operations. |
| 101 builder.CreateArguments(CreateArgumentsType::kMappedArguments) | 95 builder.CreateArguments(CreateArgumentsType::kMappedArguments) |
| 102 .CreateArguments(CreateArgumentsType::kUnmappedArguments); | 96 .CreateArguments(CreateArgumentsType::kUnmappedArguments); |
| 103 | 97 |
| 104 // Emit literal creation operations. | 98 // Emit literal creation operations. |
| 105 builder.CreateRegExpLiteral(factory->NewStringFromStaticChars("a"), 0, 0) | 99 builder.CreateRegExpLiteral(factory->NewStringFromStaticChars("a"), 0, 0) |
| 106 .CreateArrayLiteral(factory->NewFixedArray(1), 0, 0) | 100 .CreateArrayLiteral(factory->NewFixedArray(1), 0, 0) |
| 107 .CreateObjectLiteral(factory->NewFixedArray(1), 0, 0); | 101 .CreateObjectLiteral(factory->NewFixedArray(1), 0, 0); |
| 108 | 102 |
| 109 // Call operations. | 103 // Call operations. |
| 110 builder.Call(reg, reg, 0, 0) | 104 builder.Call(reg, other, 1, 0) |
| 111 .Call(reg, reg, 0, 1024) | 105 .Call(reg, wide, 1, 0) |
| 112 .CallRuntime(Runtime::kIsArray, reg, 1) | 106 .CallRuntime(Runtime::kIsArray, reg, 1) |
| 113 .CallRuntimeForPair(Runtime::kLoadLookupSlot, reg, 1, reg) | 107 .CallRuntime(Runtime::kIsArray, wide, 1) |
| 114 .CallJSRuntime(Context::SPREAD_ITERABLE_INDEX, reg, 1); | 108 .CallRuntimeForPair(Runtime::kLoadLookupSlot, reg, 1, other) |
| 109 .CallRuntimeForPair(Runtime::kLoadLookupSlot, wide, 1, other) |
| 110 .CallJSRuntime(Context::SPREAD_ITERABLE_INDEX, reg, 1) |
| 111 .CallJSRuntime(Context::SPREAD_ITERABLE_INDEX, wide, 1); |
| 115 | 112 |
| 116 // Emit binary operator invocations. | 113 // Emit binary operator invocations. |
| 117 builder.BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) | 114 builder.BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) |
| 118 .BinaryOperation(Token::Value::SUB, reg, Strength::WEAK) | 115 .BinaryOperation(Token::Value::SUB, reg, Strength::WEAK) |
| 119 .BinaryOperation(Token::Value::MUL, reg, Strength::WEAK) | 116 .BinaryOperation(Token::Value::MUL, reg, Strength::WEAK) |
| 120 .BinaryOperation(Token::Value::DIV, reg, Strength::WEAK) | 117 .BinaryOperation(Token::Value::DIV, reg, Strength::WEAK) |
| 121 .BinaryOperation(Token::Value::MOD, reg, Strength::WEAK); | 118 .BinaryOperation(Token::Value::MOD, reg, Strength::WEAK); |
| 122 | 119 |
| 123 // Emit bitwise operator invocations | 120 // Emit bitwise operator invocations |
| 124 builder.BinaryOperation(Token::Value::BIT_OR, reg, Strength::WEAK) | 121 builder.BinaryOperation(Token::Value::BIT_OR, reg, Strength::WEAK) |
| (...skipping 12 matching lines...) Expand all Loading... |
| 137 // Emit unary operator invocations. | 134 // Emit unary operator invocations. |
| 138 builder.LogicalNot().TypeOf(); | 135 builder.LogicalNot().TypeOf(); |
| 139 | 136 |
| 140 // Emit delete | 137 // Emit delete |
| 141 builder.Delete(reg, LanguageMode::SLOPPY) | 138 builder.Delete(reg, LanguageMode::SLOPPY) |
| 142 .Delete(reg, LanguageMode::STRICT) | 139 .Delete(reg, LanguageMode::STRICT) |
| 143 .DeleteLookupSlot(); | 140 .DeleteLookupSlot(); |
| 144 | 141 |
| 145 // Emit new. | 142 // Emit new. |
| 146 builder.New(reg, reg, 0); | 143 builder.New(reg, reg, 0); |
| 144 builder.New(wide, wide, 0); |
| 147 | 145 |
| 148 // Emit test operator invocations. | 146 // Emit test operator invocations. |
| 149 builder.CompareOperation(Token::Value::EQ, reg, Strength::WEAK) | 147 builder.CompareOperation(Token::Value::EQ, reg, Strength::WEAK) |
| 150 .CompareOperation(Token::Value::NE, reg, Strength::WEAK) | 148 .CompareOperation(Token::Value::NE, reg, Strength::WEAK) |
| 151 .CompareOperation(Token::Value::EQ_STRICT, reg, Strength::WEAK) | 149 .CompareOperation(Token::Value::EQ_STRICT, reg, Strength::WEAK) |
| 152 .CompareOperation(Token::Value::NE_STRICT, reg, Strength::WEAK) | 150 .CompareOperation(Token::Value::NE_STRICT, reg, Strength::WEAK) |
| 153 .CompareOperation(Token::Value::LT, reg, Strength::WEAK) | 151 .CompareOperation(Token::Value::LT, reg, Strength::WEAK) |
| 154 .CompareOperation(Token::Value::GT, reg, Strength::WEAK) | 152 .CompareOperation(Token::Value::GT, reg, Strength::WEAK) |
| 155 .CompareOperation(Token::Value::LTE, reg, Strength::WEAK) | 153 .CompareOperation(Token::Value::LTE, reg, Strength::WEAK) |
| 156 .CompareOperation(Token::Value::GTE, reg, Strength::WEAK) | 154 .CompareOperation(Token::Value::GTE, reg, Strength::WEAK) |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 198 // Perform an operation that returns a non-boolean operation to | 196 // Perform an operation that returns a non-boolean operation to |
| 199 // generate JumpIfToBooleanTrue/False. | 197 // generate JumpIfToBooleanTrue/False. |
| 200 builder.BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) | 198 builder.BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) |
| 201 .JumpIfTrue(&start) | 199 .JumpIfTrue(&start) |
| 202 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) | 200 .BinaryOperation(Token::Value::ADD, reg, Strength::WEAK) |
| 203 .JumpIfFalse(&start); | 201 .JumpIfFalse(&start); |
| 204 | 202 |
| 205 // Emit throw in it's own basic block so that the rest of the code isn't | 203 // Emit throw in it's own basic block so that the rest of the code isn't |
| 206 // omitted due to being dead. | 204 // omitted due to being dead. |
| 207 BytecodeLabel after_throw; | 205 BytecodeLabel after_throw; |
| 208 builder.Jump(&after_throw) | 206 builder.Jump(&after_throw).Throw().Bind(&after_throw); |
| 209 .Throw() | |
| 210 .Bind(&after_throw); | |
| 211 | 207 |
| 212 builder.ForInPrepare(reg) | 208 builder.ForInPrepare(reg) |
| 213 .ForInDone(reg, reg) | 209 .ForInDone(reg, reg) |
| 214 .ForInNext(reg, reg, reg) | 210 .ForInNext(reg, reg, reg) |
| 215 .ForInStep(reg); | 211 .ForInStep(reg); |
| 212 builder.ForInPrepare(wide) |
| 213 .ForInDone(reg, other) |
| 214 .ForInNext(wide, wide, wide) |
| 215 .ForInStep(reg); |
| 216 | 216 |
| 217 // Wide constant pool loads | 217 // Wide constant pool loads |
| 218 for (int i = 0; i < 256; i++) { | 218 for (int i = 0; i < 256; i++) { |
| 219 // Emit junk in constant pool to force wide constant pool index. | 219 // Emit junk in constant pool to force wide constant pool index. |
| 220 builder.LoadLiteral(factory->NewNumber(2.5321 + i)); | 220 builder.LoadLiteral(factory->NewNumber(2.5321 + i)); |
| 221 } | 221 } |
| 222 builder.LoadLiteral(Smi::FromInt(20000000)); | 222 builder.LoadLiteral(Smi::FromInt(20000000)); |
| 223 Handle<String> wide_name = factory->NewStringFromStaticChars("var_wide_name"); | 223 Handle<String> wide_name = factory->NewStringFromStaticChars("var_wide_name"); |
| 224 | 224 |
| 225 // Emit wide global load / store operations. | 225 // Emit wide global load / store operations. |
| (...skipping 10 matching lines...) Expand all Loading... |
| 236 builder.LoadNamedProperty(reg, wide_name, 0, LanguageMode::SLOPPY) | 236 builder.LoadNamedProperty(reg, wide_name, 0, LanguageMode::SLOPPY) |
| 237 .LoadKeyedProperty(reg, 2056, LanguageMode::SLOPPY) | 237 .LoadKeyedProperty(reg, 2056, LanguageMode::SLOPPY) |
| 238 .StoreNamedProperty(reg, wide_name, 0, LanguageMode::SLOPPY) | 238 .StoreNamedProperty(reg, wide_name, 0, LanguageMode::SLOPPY) |
| 239 .StoreKeyedProperty(reg, reg, 2056, LanguageMode::SLOPPY) | 239 .StoreKeyedProperty(reg, reg, 2056, LanguageMode::SLOPPY) |
| 240 .LoadNamedProperty(reg, wide_name, 0, LanguageMode::STRICT) | 240 .LoadNamedProperty(reg, wide_name, 0, LanguageMode::STRICT) |
| 241 .LoadKeyedProperty(reg, 2056, LanguageMode::STRICT) | 241 .LoadKeyedProperty(reg, 2056, LanguageMode::STRICT) |
| 242 .StoreNamedProperty(reg, wide_name, 0, LanguageMode::STRICT) | 242 .StoreNamedProperty(reg, wide_name, 0, LanguageMode::STRICT) |
| 243 .StoreKeyedProperty(reg, reg, 2056, LanguageMode::STRICT); | 243 .StoreKeyedProperty(reg, reg, 2056, LanguageMode::STRICT); |
| 244 | 244 |
| 245 // Emit wide context operations. | 245 // Emit wide context operations. |
| 246 builder.LoadContextSlot(reg, 1024) | 246 builder.LoadContextSlot(reg, 1024).StoreContextSlot(reg, 1024); |
| 247 .StoreContextSlot(reg, 1024); | |
| 248 | 247 |
| 249 // Emit wide load / store lookup slots. | 248 // Emit wide load / store lookup slots. |
| 250 builder.LoadLookupSlot(wide_name, TypeofMode::NOT_INSIDE_TYPEOF) | 249 builder.LoadLookupSlot(wide_name, TypeofMode::NOT_INSIDE_TYPEOF) |
| 251 .LoadLookupSlot(wide_name, TypeofMode::INSIDE_TYPEOF) | 250 .LoadLookupSlot(wide_name, TypeofMode::INSIDE_TYPEOF) |
| 252 .StoreLookupSlot(wide_name, LanguageMode::SLOPPY) | 251 .StoreLookupSlot(wide_name, LanguageMode::SLOPPY) |
| 253 .StoreLookupSlot(wide_name, LanguageMode::STRICT); | 252 .StoreLookupSlot(wide_name, LanguageMode::STRICT); |
| 254 | 253 |
| 255 // CreateClosureWide | 254 // CreateClosureWide |
| 256 Handle<SharedFunctionInfo> shared_info2 = factory->NewSharedFunctionInfo( | 255 Handle<SharedFunctionInfo> shared_info2 = factory->NewSharedFunctionInfo( |
| 257 factory->NewStringFromStaticChars("function_b"), MaybeHandle<Code>(), | 256 factory->NewStringFromStaticChars("function_b"), MaybeHandle<Code>(), |
| (...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 683 } | 682 } |
| 684 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); | 683 CHECK_EQ(iterator.current_bytecode(), Bytecode::kReturn); |
| 685 iterator.Advance(); | 684 iterator.Advance(); |
| 686 CHECK(iterator.done()); | 685 CHECK(iterator.done()); |
| 687 } | 686 } |
| 688 | 687 |
| 689 | 688 |
| 690 } // namespace interpreter | 689 } // namespace interpreter |
| 691 } // namespace internal | 690 } // namespace internal |
| 692 } // namespace v8 | 691 } // namespace v8 |
| OLD | NEW |