| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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/compiler/interpreter-assembler.h" | 5 #include "src/compiler/interpreter-assembler.h" |
| 6 | 6 |
| 7 #include <ostream> | 7 #include <ostream> |
| 8 | 8 |
| 9 #include "src/code-factory.h" | 9 #include "src/code-factory.h" |
| 10 #include "src/compiler/graph.h" | 10 #include "src/compiler/graph.h" |
| (...skipping 12 matching lines...) Expand all Loading... |
| 23 namespace v8 { | 23 namespace v8 { |
| 24 namespace internal { | 24 namespace internal { |
| 25 namespace compiler { | 25 namespace compiler { |
| 26 | 26 |
| 27 | 27 |
| 28 InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone, | 28 InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone, |
| 29 interpreter::Bytecode bytecode) | 29 interpreter::Bytecode bytecode) |
| 30 : bytecode_(bytecode), | 30 : bytecode_(bytecode), |
| 31 raw_assembler_(new RawMachineAssembler( | 31 raw_assembler_(new RawMachineAssembler( |
| 32 isolate, new (zone) Graph(zone), | 32 isolate, new (zone) Graph(zone), |
| 33 Linkage::GetInterpreterDispatchDescriptor(zone), kMachPtr, | 33 Linkage::GetInterpreterDispatchDescriptor(zone), |
| 34 MachineType::PointerRepresentation(), |
| 34 InstructionSelector::SupportedMachineOperatorFlags())), | 35 InstructionSelector::SupportedMachineOperatorFlags())), |
| 35 accumulator_( | 36 accumulator_( |
| 36 raw_assembler_->Parameter(Linkage::kInterpreterAccumulatorParameter)), | 37 raw_assembler_->Parameter(Linkage::kInterpreterAccumulatorParameter)), |
| 37 context_( | 38 context_( |
| 38 raw_assembler_->Parameter(Linkage::kInterpreterContextParameter)), | 39 raw_assembler_->Parameter(Linkage::kInterpreterContextParameter)), |
| 39 code_generated_(false) {} | 40 code_generated_(false) {} |
| 40 | 41 |
| 41 | 42 |
| 42 InterpreterAssembler::~InterpreterAssembler() {} | 43 InterpreterAssembler::~InterpreterAssembler() {} |
| 43 | 44 |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 105 } | 106 } |
| 106 | 107 |
| 107 | 108 |
| 108 Node* InterpreterAssembler::RegisterLocation(Node* reg_index) { | 109 Node* InterpreterAssembler::RegisterLocation(Node* reg_index) { |
| 109 return IntPtrAdd(RegisterFileRawPointer(), RegisterFrameOffset(reg_index)); | 110 return IntPtrAdd(RegisterFileRawPointer(), RegisterFrameOffset(reg_index)); |
| 110 } | 111 } |
| 111 | 112 |
| 112 | 113 |
| 113 Node* InterpreterAssembler::LoadRegister(interpreter::Register reg) { | 114 Node* InterpreterAssembler::LoadRegister(interpreter::Register reg) { |
| 114 return raw_assembler_->Load( | 115 return raw_assembler_->Load( |
| 115 kMachAnyTagged, RegisterFileRawPointer(), | 116 MachineType::AnyTagged(), RegisterFileRawPointer(), |
| 116 RegisterFrameOffset(Int32Constant(reg.ToOperand()))); | 117 RegisterFrameOffset(Int32Constant(reg.ToOperand()))); |
| 117 } | 118 } |
| 118 | 119 |
| 119 | 120 |
| 120 Node* InterpreterAssembler::LoadRegister(Node* reg_index) { | 121 Node* InterpreterAssembler::LoadRegister(Node* reg_index) { |
| 121 return raw_assembler_->Load(kMachAnyTagged, RegisterFileRawPointer(), | 122 return raw_assembler_->Load(MachineType::AnyTagged(), |
| 123 RegisterFileRawPointer(), |
| 122 RegisterFrameOffset(reg_index)); | 124 RegisterFrameOffset(reg_index)); |
| 123 } | 125 } |
| 124 | 126 |
| 125 | 127 |
| 126 Node* InterpreterAssembler::StoreRegister(Node* value, Node* reg_index) { | 128 Node* InterpreterAssembler::StoreRegister(Node* value, Node* reg_index) { |
| 127 return raw_assembler_->Store(kMachAnyTagged, RegisterFileRawPointer(), | 129 return raw_assembler_->Store( |
| 128 RegisterFrameOffset(reg_index), value, | 130 MachineType::AnyTagged(), RegisterFileRawPointer(), |
| 129 kNoWriteBarrier); | 131 RegisterFrameOffset(reg_index), value, kNoWriteBarrier); |
| 130 } | 132 } |
| 131 | 133 |
| 132 | 134 |
| 133 Node* InterpreterAssembler::BytecodeOperand(int operand_index) { | 135 Node* InterpreterAssembler::BytecodeOperand(int operand_index) { |
| 134 DCHECK_LT(operand_index, interpreter::Bytecodes::NumberOfOperands(bytecode_)); | 136 DCHECK_LT(operand_index, interpreter::Bytecodes::NumberOfOperands(bytecode_)); |
| 135 DCHECK_EQ(interpreter::OperandSize::kByte, | 137 DCHECK_EQ(interpreter::OperandSize::kByte, |
| 136 interpreter::Bytecodes::GetOperandSize(bytecode_, operand_index)); | 138 interpreter::Bytecodes::GetOperandSize(bytecode_, operand_index)); |
| 137 return raw_assembler_->Load( | 139 return raw_assembler_->Load( |
| 138 kMachUint8, BytecodeArrayTaggedPointer(), | 140 MachineType::Uint8(), BytecodeArrayTaggedPointer(), |
| 139 IntPtrAdd(BytecodeOffset(), | 141 IntPtrAdd(BytecodeOffset(), |
| 140 Int32Constant(interpreter::Bytecodes::GetOperandOffset( | 142 Int32Constant(interpreter::Bytecodes::GetOperandOffset( |
| 141 bytecode_, operand_index)))); | 143 bytecode_, operand_index)))); |
| 142 } | 144 } |
| 143 | 145 |
| 144 | 146 |
| 145 Node* InterpreterAssembler::BytecodeOperandSignExtended(int operand_index) { | 147 Node* InterpreterAssembler::BytecodeOperandSignExtended(int operand_index) { |
| 146 DCHECK_LT(operand_index, interpreter::Bytecodes::NumberOfOperands(bytecode_)); | 148 DCHECK_LT(operand_index, interpreter::Bytecodes::NumberOfOperands(bytecode_)); |
| 147 DCHECK_EQ(interpreter::OperandSize::kByte, | 149 DCHECK_EQ(interpreter::OperandSize::kByte, |
| 148 interpreter::Bytecodes::GetOperandSize(bytecode_, operand_index)); | 150 interpreter::Bytecodes::GetOperandSize(bytecode_, operand_index)); |
| 149 Node* load = raw_assembler_->Load( | 151 Node* load = raw_assembler_->Load( |
| 150 kMachInt8, BytecodeArrayTaggedPointer(), | 152 MachineType::Int8(), BytecodeArrayTaggedPointer(), |
| 151 IntPtrAdd(BytecodeOffset(), | 153 IntPtrAdd(BytecodeOffset(), |
| 152 Int32Constant(interpreter::Bytecodes::GetOperandOffset( | 154 Int32Constant(interpreter::Bytecodes::GetOperandOffset( |
| 153 bytecode_, operand_index)))); | 155 bytecode_, operand_index)))); |
| 154 // Ensure that we sign extend to full pointer size | 156 // Ensure that we sign extend to full pointer size |
| 155 if (kPointerSize == 8) { | 157 if (kPointerSize == 8) { |
| 156 load = raw_assembler_->ChangeInt32ToInt64(load); | 158 load = raw_assembler_->ChangeInt32ToInt64(load); |
| 157 } | 159 } |
| 158 return load; | 160 return load; |
| 159 } | 161 } |
| 160 | 162 |
| 161 | 163 |
| 162 Node* InterpreterAssembler::BytecodeOperandShort(int operand_index) { | 164 Node* InterpreterAssembler::BytecodeOperandShort(int operand_index) { |
| 163 DCHECK_LT(operand_index, interpreter::Bytecodes::NumberOfOperands(bytecode_)); | 165 DCHECK_LT(operand_index, interpreter::Bytecodes::NumberOfOperands(bytecode_)); |
| 164 DCHECK_EQ(interpreter::OperandSize::kShort, | 166 DCHECK_EQ(interpreter::OperandSize::kShort, |
| 165 interpreter::Bytecodes::GetOperandSize(bytecode_, operand_index)); | 167 interpreter::Bytecodes::GetOperandSize(bytecode_, operand_index)); |
| 166 if (TargetSupportsUnalignedAccess()) { | 168 if (TargetSupportsUnalignedAccess()) { |
| 167 return raw_assembler_->Load( | 169 return raw_assembler_->Load( |
| 168 kMachUint16, BytecodeArrayTaggedPointer(), | 170 MachineType::Uint16(), BytecodeArrayTaggedPointer(), |
| 169 IntPtrAdd(BytecodeOffset(), | 171 IntPtrAdd(BytecodeOffset(), |
| 170 Int32Constant(interpreter::Bytecodes::GetOperandOffset( | 172 Int32Constant(interpreter::Bytecodes::GetOperandOffset( |
| 171 bytecode_, operand_index)))); | 173 bytecode_, operand_index)))); |
| 172 } else { | 174 } else { |
| 173 int offset = | 175 int offset = |
| 174 interpreter::Bytecodes::GetOperandOffset(bytecode_, operand_index); | 176 interpreter::Bytecodes::GetOperandOffset(bytecode_, operand_index); |
| 175 Node* first_byte = raw_assembler_->Load( | 177 Node* first_byte = raw_assembler_->Load( |
| 176 kMachUint8, BytecodeArrayTaggedPointer(), | 178 MachineType::Uint8(), BytecodeArrayTaggedPointer(), |
| 177 IntPtrAdd(BytecodeOffset(), Int32Constant(offset))); | 179 IntPtrAdd(BytecodeOffset(), Int32Constant(offset))); |
| 178 Node* second_byte = raw_assembler_->Load( | 180 Node* second_byte = raw_assembler_->Load( |
| 179 kMachUint8, BytecodeArrayTaggedPointer(), | 181 MachineType::Uint8(), BytecodeArrayTaggedPointer(), |
| 180 IntPtrAdd(BytecodeOffset(), Int32Constant(offset + 1))); | 182 IntPtrAdd(BytecodeOffset(), Int32Constant(offset + 1))); |
| 181 #if V8_TARGET_LITTLE_ENDIAN | 183 #if V8_TARGET_LITTLE_ENDIAN |
| 182 return raw_assembler_->WordOr(WordShl(second_byte, kBitsPerByte), | 184 return raw_assembler_->WordOr(WordShl(second_byte, kBitsPerByte), |
| 183 first_byte); | 185 first_byte); |
| 184 #elif V8_TARGET_BIG_ENDIAN | 186 #elif V8_TARGET_BIG_ENDIAN |
| 185 return raw_assembler_->WordOr(WordShl(first_byte, kBitsPerByte), | 187 return raw_assembler_->WordOr(WordShl(first_byte, kBitsPerByte), |
| 186 second_byte); | 188 second_byte); |
| 187 #else | 189 #else |
| 188 #error "Unknown Architecture" | 190 #error "Unknown Architecture" |
| 189 #endif | 191 #endif |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 301 return raw_assembler_->WordShl(value, Int32Constant(shift)); | 303 return raw_assembler_->WordShl(value, Int32Constant(shift)); |
| 302 } | 304 } |
| 303 | 305 |
| 304 | 306 |
| 305 Node* InterpreterAssembler::LoadConstantPoolEntry(Node* index) { | 307 Node* InterpreterAssembler::LoadConstantPoolEntry(Node* index) { |
| 306 Node* constant_pool = LoadObjectField(BytecodeArrayTaggedPointer(), | 308 Node* constant_pool = LoadObjectField(BytecodeArrayTaggedPointer(), |
| 307 BytecodeArray::kConstantPoolOffset); | 309 BytecodeArray::kConstantPoolOffset); |
| 308 Node* entry_offset = | 310 Node* entry_offset = |
| 309 IntPtrAdd(IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag), | 311 IntPtrAdd(IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag), |
| 310 WordShl(index, kPointerSizeLog2)); | 312 WordShl(index, kPointerSizeLog2)); |
| 311 return raw_assembler_->Load(kMachAnyTagged, constant_pool, entry_offset); | 313 return raw_assembler_->Load(MachineType::AnyTagged(), constant_pool, |
| 314 entry_offset); |
| 312 } | 315 } |
| 313 | 316 |
| 314 | 317 |
| 315 Node* InterpreterAssembler::LoadFixedArrayElement(Node* fixed_array, | 318 Node* InterpreterAssembler::LoadFixedArrayElement(Node* fixed_array, |
| 316 int index) { | 319 int index) { |
| 317 Node* entry_offset = | 320 Node* entry_offset = |
| 318 IntPtrAdd(IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag), | 321 IntPtrAdd(IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag), |
| 319 WordShl(Int32Constant(index), kPointerSizeLog2)); | 322 WordShl(Int32Constant(index), kPointerSizeLog2)); |
| 320 return raw_assembler_->Load(kMachAnyTagged, fixed_array, entry_offset); | 323 return raw_assembler_->Load(MachineType::AnyTagged(), fixed_array, |
| 324 entry_offset); |
| 321 } | 325 } |
| 322 | 326 |
| 323 | 327 |
| 324 Node* InterpreterAssembler::LoadObjectField(Node* object, int offset) { | 328 Node* InterpreterAssembler::LoadObjectField(Node* object, int offset) { |
| 325 return raw_assembler_->Load(kMachAnyTagged, object, | 329 return raw_assembler_->Load(MachineType::AnyTagged(), object, |
| 326 IntPtrConstant(offset - kHeapObjectTag)); | 330 IntPtrConstant(offset - kHeapObjectTag)); |
| 327 } | 331 } |
| 328 | 332 |
| 329 | 333 |
| 330 Node* InterpreterAssembler::LoadContextSlot(Node* context, int slot_index) { | 334 Node* InterpreterAssembler::LoadContextSlot(Node* context, int slot_index) { |
| 331 return raw_assembler_->Load(kMachAnyTagged, context, | 335 return raw_assembler_->Load(MachineType::AnyTagged(), context, |
| 332 IntPtrConstant(Context::SlotOffset(slot_index))); | 336 IntPtrConstant(Context::SlotOffset(slot_index))); |
| 333 } | 337 } |
| 334 | 338 |
| 335 | 339 |
| 336 Node* InterpreterAssembler::LoadContextSlot(Node* context, Node* slot_index) { | 340 Node* InterpreterAssembler::LoadContextSlot(Node* context, Node* slot_index) { |
| 337 Node* offset = | 341 Node* offset = |
| 338 IntPtrAdd(WordShl(slot_index, kPointerSizeLog2), | 342 IntPtrAdd(WordShl(slot_index, kPointerSizeLog2), |
| 339 Int32Constant(Context::kHeaderSize - kHeapObjectTag)); | 343 Int32Constant(Context::kHeaderSize - kHeapObjectTag)); |
| 340 return raw_assembler_->Load(kMachAnyTagged, context, offset); | 344 return raw_assembler_->Load(MachineType::AnyTagged(), context, offset); |
| 341 } | 345 } |
| 342 | 346 |
| 343 | 347 |
| 344 Node* InterpreterAssembler::StoreContextSlot(Node* context, Node* slot_index, | 348 Node* InterpreterAssembler::StoreContextSlot(Node* context, Node* slot_index, |
| 345 Node* value) { | 349 Node* value) { |
| 346 Node* offset = | 350 Node* offset = |
| 347 IntPtrAdd(WordShl(slot_index, kPointerSizeLog2), | 351 IntPtrAdd(WordShl(slot_index, kPointerSizeLog2), |
| 348 Int32Constant(Context::kHeaderSize - kHeapObjectTag)); | 352 Int32Constant(Context::kHeaderSize - kHeapObjectTag)); |
| 349 return raw_assembler_->Store(kMachAnyTagged, context, offset, value, | 353 return raw_assembler_->Store(MachineType::AnyTagged(), context, offset, value, |
| 350 kFullWriteBarrier); | 354 kFullWriteBarrier); |
| 351 } | 355 } |
| 352 | 356 |
| 353 | 357 |
| 354 Node* InterpreterAssembler::LoadTypeFeedbackVector() { | 358 Node* InterpreterAssembler::LoadTypeFeedbackVector() { |
| 355 Node* function = raw_assembler_->Load( | 359 Node* function = raw_assembler_->Load( |
| 356 kMachAnyTagged, RegisterFileRawPointer(), | 360 MachineType::AnyTagged(), RegisterFileRawPointer(), |
| 357 IntPtrConstant(InterpreterFrameConstants::kFunctionFromRegisterPointer)); | 361 IntPtrConstant(InterpreterFrameConstants::kFunctionFromRegisterPointer)); |
| 358 Node* shared_info = | 362 Node* shared_info = |
| 359 LoadObjectField(function, JSFunction::kSharedFunctionInfoOffset); | 363 LoadObjectField(function, JSFunction::kSharedFunctionInfoOffset); |
| 360 Node* vector = | 364 Node* vector = |
| 361 LoadObjectField(shared_info, SharedFunctionInfo::kFeedbackVectorOffset); | 365 LoadObjectField(shared_info, SharedFunctionInfo::kFeedbackVectorOffset); |
| 362 return vector; | 366 return vector; |
| 363 } | 367 } |
| 364 | 368 |
| 365 | 369 |
| 366 Node* InterpreterAssembler::CallConstruct(Node* new_target, Node* constructor, | 370 Node* InterpreterAssembler::CallConstruct(Node* new_target, Node* constructor, |
| (...skipping 103 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 470 isolate(), zone(), callable.descriptor(), 0, CallDescriptor::kNoFlags); | 474 isolate(), zone(), callable.descriptor(), 0, CallDescriptor::kNoFlags); |
| 471 | 475 |
| 472 Node* code_target = HeapConstant(callable.code()); | 476 Node* code_target = HeapConstant(callable.code()); |
| 473 | 477 |
| 474 // Get the function entry from the function id. | 478 // Get the function entry from the function id. |
| 475 Node* function_table = raw_assembler_->ExternalConstant( | 479 Node* function_table = raw_assembler_->ExternalConstant( |
| 476 ExternalReference::runtime_function_table_address(isolate())); | 480 ExternalReference::runtime_function_table_address(isolate())); |
| 477 Node* function_offset = raw_assembler_->Int32Mul( | 481 Node* function_offset = raw_assembler_->Int32Mul( |
| 478 function_id, Int32Constant(sizeof(Runtime::Function))); | 482 function_id, Int32Constant(sizeof(Runtime::Function))); |
| 479 Node* function = IntPtrAdd(function_table, function_offset); | 483 Node* function = IntPtrAdd(function_table, function_offset); |
| 480 Node* function_entry = raw_assembler_->Load( | 484 Node* function_entry = |
| 481 kMachPtr, function, Int32Constant(offsetof(Runtime::Function, entry))); | 485 raw_assembler_->Load(MachineType::Pointer(), function, |
| 486 Int32Constant(offsetof(Runtime::Function, entry))); |
| 482 | 487 |
| 483 Node** args = zone()->NewArray<Node*>(4); | 488 Node** args = zone()->NewArray<Node*>(4); |
| 484 args[0] = arg_count; | 489 args[0] = arg_count; |
| 485 args[1] = first_arg; | 490 args[1] = first_arg; |
| 486 args[2] = function_entry; | 491 args[2] = function_entry; |
| 487 args[3] = GetContext(); | 492 args[3] = GetContext(); |
| 488 | 493 |
| 489 return CallN(descriptor, code_target, args); | 494 return CallN(descriptor, code_target, args); |
| 490 } | 495 } |
| 491 | 496 |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 555 } | 560 } |
| 556 | 561 |
| 557 | 562 |
| 558 void InterpreterAssembler::Dispatch() { | 563 void InterpreterAssembler::Dispatch() { |
| 559 DispatchTo(Advance(interpreter::Bytecodes::Size(bytecode_))); | 564 DispatchTo(Advance(interpreter::Bytecodes::Size(bytecode_))); |
| 560 } | 565 } |
| 561 | 566 |
| 562 | 567 |
| 563 void InterpreterAssembler::DispatchTo(Node* new_bytecode_offset) { | 568 void InterpreterAssembler::DispatchTo(Node* new_bytecode_offset) { |
| 564 Node* target_bytecode = raw_assembler_->Load( | 569 Node* target_bytecode = raw_assembler_->Load( |
| 565 kMachUint8, BytecodeArrayTaggedPointer(), new_bytecode_offset); | 570 MachineType::Uint8(), BytecodeArrayTaggedPointer(), new_bytecode_offset); |
| 566 | 571 |
| 567 // TODO(rmcilroy): Create a code target dispatch table to avoid conversion | 572 // TODO(rmcilroy): Create a code target dispatch table to avoid conversion |
| 568 // from code object on every dispatch. | 573 // from code object on every dispatch. |
| 569 Node* target_code_object = raw_assembler_->Load( | 574 Node* target_code_object = raw_assembler_->Load( |
| 570 kMachPtr, DispatchTableRawPointer(), | 575 MachineType::Pointer(), DispatchTableRawPointer(), |
| 571 raw_assembler_->Word32Shl(target_bytecode, | 576 raw_assembler_->Word32Shl(target_bytecode, |
| 572 Int32Constant(kPointerSizeLog2))); | 577 Int32Constant(kPointerSizeLog2))); |
| 573 | 578 |
| 574 // If the order of the parameters you need to change the call signature below. | 579 // If the order of the parameters you need to change the call signature below. |
| 575 STATIC_ASSERT(0 == Linkage::kInterpreterAccumulatorParameter); | 580 STATIC_ASSERT(0 == Linkage::kInterpreterAccumulatorParameter); |
| 576 STATIC_ASSERT(1 == Linkage::kInterpreterRegisterFileParameter); | 581 STATIC_ASSERT(1 == Linkage::kInterpreterRegisterFileParameter); |
| 577 STATIC_ASSERT(2 == Linkage::kInterpreterBytecodeOffsetParameter); | 582 STATIC_ASSERT(2 == Linkage::kInterpreterBytecodeOffsetParameter); |
| 578 STATIC_ASSERT(3 == Linkage::kInterpreterBytecodeArrayParameter); | 583 STATIC_ASSERT(3 == Linkage::kInterpreterBytecodeArrayParameter); |
| 579 STATIC_ASSERT(4 == Linkage::kInterpreterDispatchTableParameter); | 584 STATIC_ASSERT(4 == Linkage::kInterpreterDispatchTableParameter); |
| 580 STATIC_ASSERT(5 == Linkage::kInterpreterContextParameter); | 585 STATIC_ASSERT(5 == Linkage::kInterpreterContextParameter); |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 631 return raw_assembler_->call_descriptor(); | 636 return raw_assembler_->call_descriptor(); |
| 632 } | 637 } |
| 633 | 638 |
| 634 | 639 |
| 635 Zone* InterpreterAssembler::zone() { return raw_assembler_->zone(); } | 640 Zone* InterpreterAssembler::zone() { return raw_assembler_->zone(); } |
| 636 | 641 |
| 637 | 642 |
| 638 } // namespace compiler | 643 } // namespace compiler |
| 639 } // namespace internal | 644 } // namespace internal |
| 640 } // namespace v8 | 645 } // namespace v8 |
| OLD | NEW |