| Index: src/compiler/interpreter-assembler.cc
|
| diff --git a/src/compiler/interpreter-assembler.cc b/src/compiler/interpreter-assembler.cc
|
| index 35ddb074275ac06fc6b7587880a29bc954511300..4bd399520d414e9923065d56fb3d02389d2185c3 100644
|
| --- a/src/compiler/interpreter-assembler.cc
|
| +++ b/src/compiler/interpreter-assembler.cc
|
| @@ -34,6 +34,8 @@ InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone,
|
| InstructionSelector::SupportedMachineOperatorFlags())),
|
| accumulator_(
|
| raw_assembler_->Parameter(Linkage::kInterpreterAccumulatorParameter)),
|
| + bytecode_offset_(raw_assembler_->Parameter(
|
| + Linkage::kInterpreterBytecodeOffsetParameter)),
|
| context_(
|
| raw_assembler_->Parameter(Linkage::kInterpreterContextParameter)),
|
| code_generated_(false) {}
|
| @@ -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,31 +95,29 @@ 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(kMachAnyTagged, 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);
|
| }
|
|
|
|
|
| @@ -124,6 +127,18 @@ Node* InterpreterAssembler::LoadRegister(Node* reg_index) {
|
| }
|
|
|
|
|
| +Node* InterpreterAssembler::StoreRegister(Node* value, int offset) {
|
| + return raw_assembler_->Store(kMachAnyTagged, 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,
|
| @@ -379,12 +394,49 @@ Node* InterpreterAssembler::CallConstruct(Node* new_target, Node* constructor,
|
| args[3] = first_arg;
|
| args[4] = GetContext();
|
|
|
| - return CallN(descriptor, code_target, args);
|
| + return CallN(descriptor, code_target, args,
|
| + SaveAccumulatorMode::kClobberAccumulator);
|
| +}
|
| +
|
| +
|
| +void InterpreterAssembler::CallPrologue(
|
| + SaveAccumulatorMode save_accumulator_mode) {
|
| + if (save_accumulator_mode == SaveAccumulatorMode::kSaveAccumulator) {
|
| + StoreRegister(
|
| + accumulator_,
|
| + InterpreterFrameConstants::kSavedAccumulatorFromRegisterPointer);
|
| + } else {
|
| + DCHECK(save_accumulator_mode == SaveAccumulatorMode::kClobberAccumulator);
|
| + }
|
| +
|
| + StoreRegister(SmiTag(bytecode_offset_),
|
| + InterpreterFrameConstants::kBytecodeOffsetFromRegisterPointer);
|
| +}
|
| +
|
| +
|
| +void InterpreterAssembler::CallEpilogue(
|
| + SaveAccumulatorMode save_accumulator_mode) {
|
| + // Restore the bytecode offset from the stack frame.
|
| + bytecode_offset_ = SmiUntag(LoadRegister(
|
| + InterpreterFrameConstants::kBytecodeOffsetFromRegisterPointer));
|
| +
|
| + if (save_accumulator_mode == SaveAccumulatorMode::kSaveAccumulator) {
|
| + // Restore accumulator from stack frame.
|
| + accumulator_ = LoadRegister(
|
| + InterpreterFrameConstants::kSavedAccumulatorFromRegisterPointer);
|
| + } else {
|
| + // Clobber the accumulator.
|
| + DCHECK(save_accumulator_mode == SaveAccumulatorMode::kClobberAccumulator);
|
| + accumulator_ = nullptr;
|
| + }
|
| }
|
|
|
|
|
| Node* InterpreterAssembler::CallN(CallDescriptor* descriptor, Node* code_target,
|
| - Node** args) {
|
| + Node** args,
|
| + SaveAccumulatorMode save_accumulator_mode) {
|
| + CallPrologue(save_accumulator_mode);
|
| +
|
| Node* stack_pointer_before_call = nullptr;
|
| if (FLAG_debug_code) {
|
| stack_pointer_before_call = raw_assembler_->LoadStackPointer();
|
| @@ -395,6 +447,8 @@ Node* InterpreterAssembler::CallN(CallDescriptor* descriptor, Node* code_target,
|
| AbortIfWordNotEqual(stack_pointer_before_call, stack_pointer_after_call,
|
| kUnexpectedStackPointer);
|
| }
|
| +
|
| + CallEpilogue(save_accumulator_mode);
|
| return return_val;
|
| }
|
|
|
| @@ -413,46 +467,51 @@ Node* InterpreterAssembler::CallJS(Node* function, Node* first_arg,
|
| args[2] = function;
|
| args[3] = GetContext();
|
|
|
| - return CallN(descriptor, code_target, args);
|
| + return CallN(descriptor, code_target, args,
|
| + SaveAccumulatorMode::kClobberAccumulator);
|
| }
|
|
|
|
|
| Node* InterpreterAssembler::CallIC(CallInterfaceDescriptor descriptor,
|
| - Node* target, Node** args) {
|
| + Node* target, Node** args,
|
| + SaveAccumulatorMode save_accumulator_mode) {
|
| CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
|
| isolate(), zone(), descriptor, 0, CallDescriptor::kNoFlags);
|
| - return CallN(call_descriptor, target, args);
|
| + return CallN(call_descriptor, target, args, save_accumulator_mode);
|
| }
|
|
|
|
|
| Node* InterpreterAssembler::CallIC(CallInterfaceDescriptor descriptor,
|
| Node* target, Node* arg1, Node* arg2,
|
| - Node* arg3) {
|
| + Node* arg3,
|
| + SaveAccumulatorMode save_accumulator_mode) {
|
| Node** args = zone()->NewArray<Node*>(4);
|
| args[0] = arg1;
|
| args[1] = arg2;
|
| args[2] = arg3;
|
| args[3] = GetContext();
|
| - return CallIC(descriptor, target, args);
|
| + return CallIC(descriptor, target, args, save_accumulator_mode);
|
| }
|
|
|
|
|
| Node* InterpreterAssembler::CallIC(CallInterfaceDescriptor descriptor,
|
| Node* target, Node* arg1, Node* arg2,
|
| - Node* arg3, Node* arg4) {
|
| + Node* arg3, Node* arg4,
|
| + SaveAccumulatorMode save_accumulator_mode) {
|
| Node** args = zone()->NewArray<Node*>(5);
|
| args[0] = arg1;
|
| args[1] = arg2;
|
| args[2] = arg3;
|
| args[3] = arg4;
|
| args[4] = GetContext();
|
| - return CallIC(descriptor, target, args);
|
| + return CallIC(descriptor, target, args, save_accumulator_mode);
|
| }
|
|
|
|
|
| Node* InterpreterAssembler::CallIC(CallInterfaceDescriptor descriptor,
|
| Node* target, Node* arg1, Node* arg2,
|
| - Node* arg3, Node* arg4, Node* arg5) {
|
| + Node* arg3, Node* arg4, Node* arg5,
|
| + SaveAccumulatorMode save_accumulator_mode) {
|
| Node** args = zone()->NewArray<Node*>(6);
|
| args[0] = arg1;
|
| args[1] = arg2;
|
| @@ -460,12 +519,13 @@ Node* InterpreterAssembler::CallIC(CallInterfaceDescriptor descriptor,
|
| args[3] = arg4;
|
| args[4] = arg5;
|
| args[5] = GetContext();
|
| - return CallIC(descriptor, target, args);
|
| + return CallIC(descriptor, target, args, save_accumulator_mode);
|
| }
|
|
|
|
|
| -Node* InterpreterAssembler::CallRuntime(Node* function_id, Node* first_arg,
|
| - Node* arg_count) {
|
| +Node* InterpreterAssembler::CallRuntime(
|
| + Node* function_id, Node* first_arg, Node* arg_count,
|
| + SaveAccumulatorMode save_accumulator_mode) {
|
| Callable callable = CodeFactory::InterpreterCEntry(isolate());
|
| CallDescriptor* descriptor = Linkage::GetStubCallDescriptor(
|
| isolate(), zone(), callable.descriptor(), 0, CallDescriptor::kNoFlags);
|
| @@ -487,27 +547,40 @@ Node* InterpreterAssembler::CallRuntime(Node* function_id, Node* first_arg,
|
| args[2] = function_entry;
|
| args[3] = GetContext();
|
|
|
| - return CallN(descriptor, code_target, args);
|
| + return CallN(descriptor, code_target, args, save_accumulator_mode);
|
| }
|
|
|
|
|
| -Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id,
|
| - Node* arg1) {
|
| - return raw_assembler_->CallRuntime1(function_id, arg1, GetContext());
|
| +Node* InterpreterAssembler::CallRuntime(
|
| + Runtime::FunctionId function_id, Node* arg1,
|
| + SaveAccumulatorMode save_accumulator_mode) {
|
| + CallPrologue(save_accumulator_mode);
|
| + Node* return_val =
|
| + raw_assembler_->CallRuntime1(function_id, arg1, GetContext());
|
| + CallEpilogue(save_accumulator_mode);
|
| + return return_val;
|
| }
|
|
|
|
|
| -Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id,
|
| - Node* arg1, Node* arg2) {
|
| - return raw_assembler_->CallRuntime2(function_id, arg1, arg2, GetContext());
|
| +Node* InterpreterAssembler::CallRuntime(
|
| + Runtime::FunctionId function_id, Node* arg1, Node* arg2,
|
| + SaveAccumulatorMode save_accumulator_mode) {
|
| + CallPrologue(save_accumulator_mode);
|
| + Node* return_val =
|
| + raw_assembler_->CallRuntime2(function_id, arg1, arg2, GetContext());
|
| + CallEpilogue(save_accumulator_mode);
|
| + 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());
|
| +Node* InterpreterAssembler::CallRuntime(
|
| + Runtime::FunctionId function_id, Node* arg1, Node* arg2, Node* arg3,
|
| + Node* arg4, SaveAccumulatorMode save_accumulator_mode) {
|
| + CallPrologue(save_accumulator_mode);
|
| + Node* return_val = raw_assembler_->CallRuntime4(function_id, arg1, arg2, arg3,
|
| + arg4, GetContext());
|
| + CallEpilogue(save_accumulator_mode);
|
| + return return_val;
|
| }
|
|
|
|
|
| @@ -591,8 +664,9 @@ void InterpreterAssembler::DispatchTo(Node* new_bytecode_offset) {
|
|
|
| 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);
|
| }
|
|
|
|
|
|
|