diff options
Diffstat (limited to 'deps/v8/src/compiler/interpreter-assembler.cc')
-rw-r--r-- | deps/v8/src/compiler/interpreter-assembler.cc | 286 |
1 files changed, 191 insertions, 95 deletions
diff --git a/deps/v8/src/compiler/interpreter-assembler.cc b/deps/v8/src/compiler/interpreter-assembler.cc index ed056cfe56..7080d02120 100644 --- a/deps/v8/src/compiler/interpreter-assembler.cc +++ b/deps/v8/src/compiler/interpreter-assembler.cc @@ -10,13 +10,13 @@ #include "src/compiler/graph.h" #include "src/compiler/instruction-selector.h" #include "src/compiler/linkage.h" -#include "src/compiler/machine-type.h" #include "src/compiler/pipeline.h" #include "src/compiler/raw-machine-assembler.h" #include "src/compiler/schedule.h" #include "src/frames.h" #include "src/interface-descriptors.h" #include "src/interpreter/bytecodes.h" +#include "src/machine-type.h" #include "src/macro-assembler.h" #include "src/zone.h" @@ -30,11 +30,13 @@ InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone, : bytecode_(bytecode), raw_assembler_(new RawMachineAssembler( isolate, new (zone) Graph(zone), - Linkage::GetInterpreterDispatchDescriptor(zone), kMachPtr, + Linkage::GetInterpreterDispatchDescriptor(zone), + MachineType::PointerRepresentation(), InstructionSelector::SupportedMachineOperatorFlags())), - end_nodes_(zone), accumulator_( raw_assembler_->Parameter(Linkage::kInterpreterAccumulatorParameter)), + bytecode_offset_(raw_assembler_->Parameter( + Linkage::kInterpreterBytecodeOffsetParameter)), context_( raw_assembler_->Parameter(Linkage::kInterpreterContextParameter)), code_generated_(false) {} @@ -46,14 +48,14 @@ InterpreterAssembler::~InterpreterAssembler() {} Handle<Code> InterpreterAssembler::GenerateCode() { DCHECK(!code_generated_); - End(); + // Disallow empty handlers that never return. + DCHECK_NE(0, graph()->end()->InputCount()); const char* bytecode_name = interpreter::Bytecodes::ToString(bytecode_); Schedule* schedule = raw_assembler_->Export(); - // TODO(rmcilroy): use a non-testing code generator. - Handle<Code> code = Pipeline::GenerateCodeForInterpreter( + Handle<Code> code = Pipeline::GenerateCodeForCodeStub( isolate(), raw_assembler_->call_descriptor(), graph(), schedule, - bytecode_name); + Code::STUB, bytecode_name); #ifdef ENABLE_DISASSEMBLER if (FLAG_trace_ignition_codegen) { @@ -80,6 +82,9 @@ Node* InterpreterAssembler::GetContext() { return context_; } void InterpreterAssembler::SetContext(Node* value) { context_ = value; } +Node* InterpreterAssembler::BytecodeOffset() { return bytecode_offset_; } + + Node* InterpreterAssembler::RegisterFileRawPointer() { return raw_assembler_->Parameter(Linkage::kInterpreterRegisterFileParameter); } @@ -90,44 +95,62 @@ Node* InterpreterAssembler::BytecodeArrayTaggedPointer() { } -Node* InterpreterAssembler::BytecodeOffset() { - return raw_assembler_->Parameter( - Linkage::kInterpreterBytecodeOffsetParameter); -} - - Node* InterpreterAssembler::DispatchTableRawPointer() { return raw_assembler_->Parameter(Linkage::kInterpreterDispatchTableParameter); } -Node* InterpreterAssembler::RegisterFrameOffset(Node* index) { - return WordShl(index, kPointerSizeLog2); +Node* InterpreterAssembler::RegisterLocation(Node* reg_index) { + return IntPtrAdd(RegisterFileRawPointer(), RegisterFrameOffset(reg_index)); } -Node* InterpreterAssembler::RegisterLocation(Node* reg_index) { - return IntPtrAdd(RegisterFileRawPointer(), RegisterFrameOffset(reg_index)); +Node* InterpreterAssembler::LoadRegister(int offset) { + return raw_assembler_->Load(MachineType::AnyTagged(), + RegisterFileRawPointer(), Int32Constant(offset)); } Node* InterpreterAssembler::LoadRegister(interpreter::Register reg) { - return raw_assembler_->Load( - kMachAnyTagged, RegisterFileRawPointer(), - RegisterFrameOffset(Int32Constant(reg.ToOperand()))); + return LoadRegister(reg.ToOperand() << kPointerSizeLog2); +} + + +Node* InterpreterAssembler::RegisterFrameOffset(Node* index) { + return WordShl(index, kPointerSizeLog2); } Node* InterpreterAssembler::LoadRegister(Node* reg_index) { - return raw_assembler_->Load(kMachAnyTagged, RegisterFileRawPointer(), + return raw_assembler_->Load(MachineType::AnyTagged(), + RegisterFileRawPointer(), RegisterFrameOffset(reg_index)); } +Node* InterpreterAssembler::StoreRegister(Node* value, int offset) { + return raw_assembler_->Store(MachineRepresentation::kTagged, + RegisterFileRawPointer(), Int32Constant(offset), + value, kNoWriteBarrier); +} + + +Node* InterpreterAssembler::StoreRegister(Node* value, + interpreter::Register reg) { + return StoreRegister(value, reg.ToOperand() << kPointerSizeLog2); +} + + Node* InterpreterAssembler::StoreRegister(Node* value, Node* reg_index) { - return raw_assembler_->Store(kMachAnyTagged, RegisterFileRawPointer(), - RegisterFrameOffset(reg_index), value, - kNoWriteBarrier); + return raw_assembler_->Store( + MachineRepresentation::kTagged, RegisterFileRawPointer(), + RegisterFrameOffset(reg_index), value, kNoWriteBarrier); +} + + +Node* InterpreterAssembler::NextRegister(Node* reg_index) { + // Register indexes are negative, so the next index is minus one. + return IntPtrAdd(reg_index, Int32Constant(-1)); } @@ -136,7 +159,7 @@ Node* InterpreterAssembler::BytecodeOperand(int operand_index) { DCHECK_EQ(interpreter::OperandSize::kByte, interpreter::Bytecodes::GetOperandSize(bytecode_, operand_index)); return raw_assembler_->Load( - kMachUint8, BytecodeArrayTaggedPointer(), + MachineType::Uint8(), BytecodeArrayTaggedPointer(), IntPtrAdd(BytecodeOffset(), Int32Constant(interpreter::Bytecodes::GetOperandOffset( bytecode_, operand_index)))); @@ -148,7 +171,7 @@ Node* InterpreterAssembler::BytecodeOperandSignExtended(int operand_index) { DCHECK_EQ(interpreter::OperandSize::kByte, interpreter::Bytecodes::GetOperandSize(bytecode_, operand_index)); Node* load = raw_assembler_->Load( - kMachInt8, BytecodeArrayTaggedPointer(), + MachineType::Int8(), BytecodeArrayTaggedPointer(), IntPtrAdd(BytecodeOffset(), Int32Constant(interpreter::Bytecodes::GetOperandOffset( bytecode_, operand_index)))); @@ -166,7 +189,7 @@ Node* InterpreterAssembler::BytecodeOperandShort(int operand_index) { interpreter::Bytecodes::GetOperandSize(bytecode_, operand_index)); if (TargetSupportsUnalignedAccess()) { return raw_assembler_->Load( - kMachUint16, BytecodeArrayTaggedPointer(), + MachineType::Uint16(), BytecodeArrayTaggedPointer(), IntPtrAdd(BytecodeOffset(), Int32Constant(interpreter::Bytecodes::GetOperandOffset( bytecode_, operand_index)))); @@ -174,10 +197,10 @@ Node* InterpreterAssembler::BytecodeOperandShort(int operand_index) { int offset = interpreter::Bytecodes::GetOperandOffset(bytecode_, operand_index); Node* first_byte = raw_assembler_->Load( - kMachUint8, BytecodeArrayTaggedPointer(), + MachineType::Uint8(), BytecodeArrayTaggedPointer(), IntPtrAdd(BytecodeOffset(), Int32Constant(offset))); Node* second_byte = raw_assembler_->Load( - kMachUint8, BytecodeArrayTaggedPointer(), + MachineType::Uint8(), BytecodeArrayTaggedPointer(), IntPtrAdd(BytecodeOffset(), Int32Constant(offset + 1))); #if V8_TARGET_LITTLE_ENDIAN return raw_assembler_->WordOr(WordShl(second_byte, kBitsPerByte), @@ -192,10 +215,62 @@ Node* InterpreterAssembler::BytecodeOperandShort(int operand_index) { } +Node* InterpreterAssembler::BytecodeOperandShortSignExtended( + int operand_index) { + DCHECK_LT(operand_index, interpreter::Bytecodes::NumberOfOperands(bytecode_)); + DCHECK_EQ(interpreter::OperandSize::kShort, + interpreter::Bytecodes::GetOperandSize(bytecode_, operand_index)); + int operand_offset = + interpreter::Bytecodes::GetOperandOffset(bytecode_, operand_index); + Node* load; + if (TargetSupportsUnalignedAccess()) { + load = raw_assembler_->Load( + MachineType::Int16(), BytecodeArrayTaggedPointer(), + IntPtrAdd(BytecodeOffset(), Int32Constant(operand_offset))); + } else { +#if V8_TARGET_LITTLE_ENDIAN + Node* hi_byte_offset = Int32Constant(operand_offset + 1); + Node* lo_byte_offset = Int32Constant(operand_offset); +#elif V8_TARGET_BIG_ENDIAN + Node* hi_byte_offset = Int32Constant(operand_offset); + Node* lo_byte_offset = Int32Constant(operand_offset + 1); +#else +#error "Unknown Architecture" +#endif + Node* hi_byte = + raw_assembler_->Load(MachineType::Int8(), BytecodeArrayTaggedPointer(), + IntPtrAdd(BytecodeOffset(), hi_byte_offset)); + Node* lo_byte = + raw_assembler_->Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(), + IntPtrAdd(BytecodeOffset(), lo_byte_offset)); + hi_byte = raw_assembler_->Word32Shl(hi_byte, Int32Constant(kBitsPerByte)); + load = raw_assembler_->Word32Or(hi_byte, lo_byte); + } + + // Ensure that we sign extend to full pointer size + if (kPointerSize == 8) { + load = raw_assembler_->ChangeInt32ToInt64(load); + } + return load; +} + + Node* InterpreterAssembler::BytecodeOperandCount(int operand_index) { - DCHECK_EQ(interpreter::OperandType::kCount8, - interpreter::Bytecodes::GetOperandType(bytecode_, operand_index)); - return BytecodeOperand(operand_index); + switch (interpreter::Bytecodes::GetOperandSize(bytecode_, operand_index)) { + case interpreter::OperandSize::kByte: + DCHECK_EQ( + interpreter::OperandType::kCount8, + interpreter::Bytecodes::GetOperandType(bytecode_, operand_index)); + return BytecodeOperand(operand_index); + case interpreter::OperandSize::kShort: + DCHECK_EQ( + interpreter::OperandType::kCount16, + interpreter::Bytecodes::GetOperandType(bytecode_, operand_index)); + return BytecodeOperandShort(operand_index); + default: + UNREACHABLE(); + return nullptr; + } } @@ -226,13 +301,23 @@ Node* InterpreterAssembler::BytecodeOperandIdx(int operand_index) { Node* InterpreterAssembler::BytecodeOperandReg(int operand_index) { -#ifdef DEBUG - interpreter::OperandType operand_type = - interpreter::Bytecodes::GetOperandType(bytecode_, operand_index); - DCHECK(operand_type == interpreter::OperandType::kReg8 || - operand_type == interpreter::OperandType::kMaybeReg8); -#endif - return BytecodeOperandSignExtended(operand_index); + switch (interpreter::Bytecodes::GetOperandType(bytecode_, operand_index)) { + case interpreter::OperandType::kReg8: + case interpreter::OperandType::kRegPair8: + case interpreter::OperandType::kMaybeReg8: + DCHECK_EQ( + interpreter::OperandSize::kByte, + interpreter::Bytecodes::GetOperandSize(bytecode_, operand_index)); + return BytecodeOperandSignExtended(operand_index); + case interpreter::OperandType::kReg16: + DCHECK_EQ( + interpreter::OperandSize::kShort, + interpreter::Bytecodes::GetOperandSize(bytecode_, operand_index)); + return BytecodeOperandShortSignExtended(operand_index); + default: + UNREACHABLE(); + return nullptr; + } } @@ -297,7 +382,8 @@ Node* InterpreterAssembler::LoadConstantPoolEntry(Node* index) { Node* entry_offset = IntPtrAdd(IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag), WordShl(index, kPointerSizeLog2)); - return raw_assembler_->Load(kMachAnyTagged, constant_pool, entry_offset); + return raw_assembler_->Load(MachineType::AnyTagged(), constant_pool, + entry_offset); } @@ -306,18 +392,19 @@ Node* InterpreterAssembler::LoadFixedArrayElement(Node* fixed_array, Node* entry_offset = IntPtrAdd(IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag), WordShl(Int32Constant(index), kPointerSizeLog2)); - return raw_assembler_->Load(kMachAnyTagged, fixed_array, entry_offset); + return raw_assembler_->Load(MachineType::AnyTagged(), fixed_array, + entry_offset); } Node* InterpreterAssembler::LoadObjectField(Node* object, int offset) { - return raw_assembler_->Load(kMachAnyTagged, object, + return raw_assembler_->Load(MachineType::AnyTagged(), object, IntPtrConstant(offset - kHeapObjectTag)); } Node* InterpreterAssembler::LoadContextSlot(Node* context, int slot_index) { - return raw_assembler_->Load(kMachAnyTagged, context, + return raw_assembler_->Load(MachineType::AnyTagged(), context, IntPtrConstant(Context::SlotOffset(slot_index))); } @@ -326,7 +413,7 @@ Node* InterpreterAssembler::LoadContextSlot(Node* context, Node* slot_index) { Node* offset = IntPtrAdd(WordShl(slot_index, kPointerSizeLog2), Int32Constant(Context::kHeaderSize - kHeapObjectTag)); - return raw_assembler_->Load(kMachAnyTagged, context, offset); + return raw_assembler_->Load(MachineType::AnyTagged(), context, offset); } @@ -335,14 +422,14 @@ Node* InterpreterAssembler::StoreContextSlot(Node* context, Node* slot_index, Node* offset = IntPtrAdd(WordShl(slot_index, kPointerSizeLog2), Int32Constant(Context::kHeaderSize - kHeapObjectTag)); - return raw_assembler_->Store(kMachAnyTagged, context, offset, value, - kFullWriteBarrier); + return raw_assembler_->Store(MachineRepresentation::kTagged, context, offset, + value, kFullWriteBarrier); } Node* InterpreterAssembler::LoadTypeFeedbackVector() { Node* function = raw_assembler_->Load( - kMachAnyTagged, RegisterFileRawPointer(), + MachineType::AnyTagged(), RegisterFileRawPointer(), IntPtrConstant(InterpreterFrameConstants::kFunctionFromRegisterPointer)); Node* shared_info = LoadObjectField(function, JSFunction::kSharedFunctionInfoOffset); @@ -352,9 +439,13 @@ Node* InterpreterAssembler::LoadTypeFeedbackVector() { } -Node* InterpreterAssembler::CallConstruct(Node* original_constructor, - Node* constructor, Node* first_arg, - Node* arg_count) { +Node* InterpreterAssembler::Projection(int index, Node* node) { + return raw_assembler_->Projection(index, node); +} + + +Node* InterpreterAssembler::CallConstruct(Node* new_target, Node* constructor, + Node* first_arg, Node* arg_count) { Callable callable = CodeFactory::InterpreterPushArgsAndConstruct(isolate()); CallDescriptor* descriptor = Linkage::GetStubCallDescriptor( isolate(), zone(), callable.descriptor(), 0, CallDescriptor::kNoFlags); @@ -363,7 +454,7 @@ Node* InterpreterAssembler::CallConstruct(Node* original_constructor, Node** args = zone()->NewArray<Node*>(5); args[0] = arg_count; - args[1] = original_constructor; + args[1] = new_target; args[2] = constructor; args[3] = first_arg; args[4] = GetContext(); @@ -372,8 +463,23 @@ Node* InterpreterAssembler::CallConstruct(Node* original_constructor, } +void InterpreterAssembler::CallPrologue() { + StoreRegister(SmiTag(bytecode_offset_), + InterpreterFrameConstants::kBytecodeOffsetFromRegisterPointer); +} + + +void InterpreterAssembler::CallEpilogue() { + // Restore the bytecode offset from the stack frame. + bytecode_offset_ = SmiUntag(LoadRegister( + InterpreterFrameConstants::kBytecodeOffsetFromRegisterPointer)); +} + + Node* InterpreterAssembler::CallN(CallDescriptor* descriptor, Node* code_target, Node** args) { + CallPrologue(); + Node* stack_pointer_before_call = nullptr; if (FLAG_debug_code) { stack_pointer_before_call = raw_assembler_->LoadStackPointer(); @@ -384,6 +490,8 @@ Node* InterpreterAssembler::CallN(CallDescriptor* descriptor, Node* code_target, AbortIfWordNotEqual(stack_pointer_before_call, stack_pointer_after_call, kUnexpectedStackPointer); } + + CallEpilogue(); return return_val; } @@ -454,11 +562,11 @@ Node* InterpreterAssembler::CallIC(CallInterfaceDescriptor descriptor, Node* InterpreterAssembler::CallRuntime(Node* function_id, Node* first_arg, - Node* arg_count) { - Callable callable = CodeFactory::InterpreterCEntry(isolate()); + Node* arg_count, int result_size) { + Callable callable = CodeFactory::InterpreterCEntry(isolate(), result_size); CallDescriptor* descriptor = Linkage::GetStubCallDescriptor( - isolate(), zone(), callable.descriptor(), 0, CallDescriptor::kNoFlags); - + isolate(), zone(), callable.descriptor(), 0, CallDescriptor::kNoFlags, + Operator::kNoProperties, MachineType::AnyTagged(), result_size); Node* code_target = HeapConstant(callable.code()); // Get the function entry from the function id. @@ -467,8 +575,9 @@ Node* InterpreterAssembler::CallRuntime(Node* function_id, Node* first_arg, Node* function_offset = raw_assembler_->Int32Mul( function_id, Int32Constant(sizeof(Runtime::Function))); Node* function = IntPtrAdd(function_table, function_offset); - Node* function_entry = raw_assembler_->Load( - kMachPtr, function, Int32Constant(offsetof(Runtime::Function, entry))); + Node* function_entry = + raw_assembler_->Load(MachineType::Pointer(), function, + Int32Constant(offsetof(Runtime::Function, entry))); Node** args = zone()->NewArray<Node*>(4); args[0] = arg_count; @@ -482,21 +591,32 @@ Node* InterpreterAssembler::CallRuntime(Node* function_id, Node* first_arg, Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id, Node* arg1) { - return raw_assembler_->CallRuntime1(function_id, arg1, GetContext()); + CallPrologue(); + Node* return_val = + raw_assembler_->CallRuntime1(function_id, arg1, GetContext()); + CallEpilogue(); + return return_val; } Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id, Node* arg1, Node* arg2) { - return raw_assembler_->CallRuntime2(function_id, arg1, arg2, GetContext()); + CallPrologue(); + Node* return_val = + raw_assembler_->CallRuntime2(function_id, arg1, arg2, GetContext()); + CallEpilogue(); + return return_val; } Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id, Node* arg1, Node* arg2, Node* arg3, Node* arg4) { - return raw_assembler_->CallRuntime4(function_id, arg1, arg2, arg3, arg4, - GetContext()); + CallPrologue(); + Node* return_val = raw_assembler_->CallRuntime4(function_id, arg1, arg2, arg3, + arg4, GetContext()); + CallEpilogue(); + return return_val; } @@ -516,10 +636,8 @@ void InterpreterAssembler::Return() { BytecodeArrayTaggedPointer(), DispatchTableRawPointer(), GetContext() }; - Node* tail_call = raw_assembler_->TailCallN( - call_descriptor(), exit_trampoline_code_object, args); - // This should always be the end node. - AddEndInput(tail_call); + raw_assembler_->TailCallN(call_descriptor(), exit_trampoline_code_object, + args); } @@ -537,7 +655,7 @@ void InterpreterAssembler::Jump(Node* delta) { DispatchTo(Advance(delta)); } void InterpreterAssembler::JumpIfWordEqual(Node* lhs, Node* rhs, Node* delta) { - RawMachineAssembler::Label match, no_match; + RawMachineLabel match, no_match; Node* condition = raw_assembler_->WordEqual(lhs, rhs); raw_assembler_->Branch(condition, &match, &no_match); raw_assembler_->Bind(&match); @@ -554,12 +672,12 @@ void InterpreterAssembler::Dispatch() { void InterpreterAssembler::DispatchTo(Node* new_bytecode_offset) { Node* target_bytecode = raw_assembler_->Load( - kMachUint8, BytecodeArrayTaggedPointer(), new_bytecode_offset); + MachineType::Uint8(), BytecodeArrayTaggedPointer(), new_bytecode_offset); // TODO(rmcilroy): Create a code target dispatch table to avoid conversion // from code object on every dispatch. Node* target_code_object = raw_assembler_->Load( - kMachPtr, DispatchTableRawPointer(), + MachineType::Pointer(), DispatchTableRawPointer(), raw_assembler_->Word32Shl(target_bytecode, Int32Constant(kPointerSizeLog2))); @@ -576,23 +694,21 @@ void InterpreterAssembler::DispatchTo(Node* new_bytecode_offset) { BytecodeArrayTaggedPointer(), DispatchTableRawPointer(), GetContext() }; - Node* tail_call = - raw_assembler_->TailCallN(call_descriptor(), target_code_object, args); - // This should always be the end node. - AddEndInput(tail_call); + raw_assembler_->TailCallN(call_descriptor(), target_code_object, args); } void InterpreterAssembler::Abort(BailoutReason bailout_reason) { Node* abort_id = SmiTag(Int32Constant(bailout_reason)); - CallRuntime(Runtime::kAbort, abort_id); - Return(); + Node* ret_value = CallRuntime(Runtime::kAbort, abort_id); + // Unreached, but keeps turbofan happy. + raw_assembler_->Return(ret_value); } void InterpreterAssembler::AbortIfWordNotEqual(Node* lhs, Node* rhs, BailoutReason bailout_reason) { - RawMachineAssembler::Label match, no_match; + RawMachineLabel match, no_match; Node* condition = raw_assembler_->WordEqual(lhs, rhs); raw_assembler_->Branch(condition, &match, &no_match); raw_assembler_->Bind(&no_match); @@ -601,21 +717,6 @@ void InterpreterAssembler::AbortIfWordNotEqual(Node* lhs, Node* rhs, } -void InterpreterAssembler::AddEndInput(Node* input) { - DCHECK_NOT_NULL(input); - end_nodes_.push_back(input); -} - - -void InterpreterAssembler::End() { - DCHECK(!end_nodes_.empty()); - int end_count = static_cast<int>(end_nodes_.size()); - Node* end = graph()->NewNode(raw_assembler_->common()->End(end_count), - end_count, &end_nodes_[0]); - graph()->SetEnd(end); -} - - // static bool InterpreterAssembler::TargetSupportsUnalignedAccess() { #if V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64 @@ -642,11 +743,6 @@ CallDescriptor* InterpreterAssembler::call_descriptor() const { } -Schedule* InterpreterAssembler::schedule() { - return raw_assembler_->schedule(); -} - - Zone* InterpreterAssembler::zone() { return raw_assembler_->zone(); } |