summaryrefslogtreecommitdiff
path: root/deps/v8/src/compiler/interpreter-assembler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/compiler/interpreter-assembler.cc')
-rw-r--r--deps/v8/src/compiler/interpreter-assembler.cc270
1 files changed, 234 insertions, 36 deletions
diff --git a/deps/v8/src/compiler/interpreter-assembler.cc b/deps/v8/src/compiler/interpreter-assembler.cc
index 1f5c0a26a5..ed056cfe56 100644
--- a/deps/v8/src/compiler/interpreter-assembler.cc
+++ b/deps/v8/src/compiler/interpreter-assembler.cc
@@ -35,6 +35,8 @@ InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone,
end_nodes_(zone),
accumulator_(
raw_assembler_->Parameter(Linkage::kInterpreterAccumulatorParameter)),
+ context_(
+ raw_assembler_->Parameter(Linkage::kInterpreterContextParameter)),
code_generated_(false) {}
@@ -66,19 +68,16 @@ Handle<Code> InterpreterAssembler::GenerateCode() {
}
-Node* InterpreterAssembler::GetAccumulator() {
- return accumulator_;
-}
+Node* InterpreterAssembler::GetAccumulator() { return accumulator_; }
-void InterpreterAssembler::SetAccumulator(Node* value) {
- accumulator_ = value;
-}
+void InterpreterAssembler::SetAccumulator(Node* value) { accumulator_ = value; }
-Node* InterpreterAssembler::ContextTaggedPointer() {
- return raw_assembler_->Parameter(Linkage::kInterpreterContextParameter);
-}
+Node* InterpreterAssembler::GetContext() { return context_; }
+
+
+void InterpreterAssembler::SetContext(Node* value) { context_ = value; }
Node* InterpreterAssembler::RegisterFileRawPointer() {
@@ -112,6 +111,13 @@ Node* InterpreterAssembler::RegisterLocation(Node* reg_index) {
}
+Node* InterpreterAssembler::LoadRegister(interpreter::Register reg) {
+ return raw_assembler_->Load(
+ kMachAnyTagged, RegisterFileRawPointer(),
+ RegisterFrameOffset(Int32Constant(reg.ToOperand())));
+}
+
+
Node* InterpreterAssembler::LoadRegister(Node* reg_index) {
return raw_assembler_->Load(kMachAnyTagged, RegisterFileRawPointer(),
RegisterFrameOffset(reg_index));
@@ -120,23 +126,32 @@ Node* InterpreterAssembler::LoadRegister(Node* reg_index) {
Node* InterpreterAssembler::StoreRegister(Node* value, Node* reg_index) {
return raw_assembler_->Store(kMachAnyTagged, RegisterFileRawPointer(),
- RegisterFrameOffset(reg_index), value);
+ RegisterFrameOffset(reg_index), value,
+ kNoWriteBarrier);
}
Node* InterpreterAssembler::BytecodeOperand(int operand_index) {
DCHECK_LT(operand_index, interpreter::Bytecodes::NumberOfOperands(bytecode_));
+ DCHECK_EQ(interpreter::OperandSize::kByte,
+ interpreter::Bytecodes::GetOperandSize(bytecode_, operand_index));
return raw_assembler_->Load(
kMachUint8, BytecodeArrayTaggedPointer(),
- IntPtrAdd(BytecodeOffset(), Int32Constant(1 + operand_index)));
+ IntPtrAdd(BytecodeOffset(),
+ Int32Constant(interpreter::Bytecodes::GetOperandOffset(
+ bytecode_, operand_index))));
}
Node* InterpreterAssembler::BytecodeOperandSignExtended(int operand_index) {
DCHECK_LT(operand_index, interpreter::Bytecodes::NumberOfOperands(bytecode_));
+ DCHECK_EQ(interpreter::OperandSize::kByte,
+ interpreter::Bytecodes::GetOperandSize(bytecode_, operand_index));
Node* load = raw_assembler_->Load(
kMachInt8, BytecodeArrayTaggedPointer(),
- IntPtrAdd(BytecodeOffset(), Int32Constant(1 + operand_index)));
+ IntPtrAdd(BytecodeOffset(),
+ Int32Constant(interpreter::Bytecodes::GetOperandOffset(
+ bytecode_, operand_index))));
// Ensure that we sign extend to full pointer size
if (kPointerSize == 8) {
load = raw_assembler_->ChangeInt32ToInt64(load);
@@ -145,14 +160,46 @@ Node* InterpreterAssembler::BytecodeOperandSignExtended(int operand_index) {
}
+Node* InterpreterAssembler::BytecodeOperandShort(int operand_index) {
+ DCHECK_LT(operand_index, interpreter::Bytecodes::NumberOfOperands(bytecode_));
+ DCHECK_EQ(interpreter::OperandSize::kShort,
+ interpreter::Bytecodes::GetOperandSize(bytecode_, operand_index));
+ if (TargetSupportsUnalignedAccess()) {
+ return raw_assembler_->Load(
+ kMachUint16, BytecodeArrayTaggedPointer(),
+ IntPtrAdd(BytecodeOffset(),
+ Int32Constant(interpreter::Bytecodes::GetOperandOffset(
+ bytecode_, operand_index))));
+ } else {
+ int offset =
+ interpreter::Bytecodes::GetOperandOffset(bytecode_, operand_index);
+ Node* first_byte = raw_assembler_->Load(
+ kMachUint8, BytecodeArrayTaggedPointer(),
+ IntPtrAdd(BytecodeOffset(), Int32Constant(offset)));
+ Node* second_byte = raw_assembler_->Load(
+ kMachUint8, BytecodeArrayTaggedPointer(),
+ IntPtrAdd(BytecodeOffset(), Int32Constant(offset + 1)));
+#if V8_TARGET_LITTLE_ENDIAN
+ return raw_assembler_->WordOr(WordShl(second_byte, kBitsPerByte),
+ first_byte);
+#elif V8_TARGET_BIG_ENDIAN
+ return raw_assembler_->WordOr(WordShl(first_byte, kBitsPerByte),
+ second_byte);
+#else
+#error "Unknown Architecture"
+#endif
+ }
+}
+
+
Node* InterpreterAssembler::BytecodeOperandCount(int operand_index) {
- DCHECK_EQ(interpreter::OperandType::kCount,
+ DCHECK_EQ(interpreter::OperandType::kCount8,
interpreter::Bytecodes::GetOperandType(bytecode_, operand_index));
return BytecodeOperand(operand_index);
}
-Node* InterpreterAssembler::BytecodeOperandImm8(int operand_index) {
+Node* InterpreterAssembler::BytecodeOperandImm(int operand_index) {
DCHECK_EQ(interpreter::OperandType::kImm8,
interpreter::Bytecodes::GetOperandType(bytecode_, operand_index));
return BytecodeOperandSignExtended(operand_index);
@@ -160,15 +207,31 @@ Node* InterpreterAssembler::BytecodeOperandImm8(int operand_index) {
Node* InterpreterAssembler::BytecodeOperandIdx(int operand_index) {
- DCHECK_EQ(interpreter::OperandType::kIdx,
- 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::kIdx8,
+ interpreter::Bytecodes::GetOperandType(bytecode_, operand_index));
+ return BytecodeOperand(operand_index);
+ case interpreter::OperandSize::kShort:
+ DCHECK_EQ(
+ interpreter::OperandType::kIdx16,
+ interpreter::Bytecodes::GetOperandType(bytecode_, operand_index));
+ return BytecodeOperandShort(operand_index);
+ default:
+ UNREACHABLE();
+ return nullptr;
+ }
}
Node* InterpreterAssembler::BytecodeOperandReg(int operand_index) {
- DCHECK_EQ(interpreter::OperandType::kReg,
- interpreter::Bytecodes::GetOperandType(bytecode_, 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);
}
@@ -238,6 +301,15 @@ Node* InterpreterAssembler::LoadConstantPoolEntry(Node* index) {
}
+Node* InterpreterAssembler::LoadFixedArrayElement(Node* fixed_array,
+ int index) {
+ Node* entry_offset =
+ IntPtrAdd(IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag),
+ WordShl(Int32Constant(index), kPointerSizeLog2));
+ return raw_assembler_->Load(kMachAnyTagged, fixed_array, entry_offset);
+}
+
+
Node* InterpreterAssembler::LoadObjectField(Node* object, int offset) {
return raw_assembler_->Load(kMachAnyTagged, object,
IntPtrConstant(offset - kHeapObjectTag));
@@ -250,8 +322,21 @@ Node* InterpreterAssembler::LoadContextSlot(Node* context, int slot_index) {
}
-Node* InterpreterAssembler::LoadContextSlot(int slot_index) {
- return LoadContextSlot(ContextTaggedPointer(), slot_index);
+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);
+}
+
+
+Node* InterpreterAssembler::StoreContextSlot(Node* context, Node* slot_index,
+ Node* value) {
+ Node* offset =
+ IntPtrAdd(WordShl(slot_index, kPointerSizeLog2),
+ Int32Constant(Context::kHeaderSize - kHeapObjectTag));
+ return raw_assembler_->Store(kMachAnyTagged, context, offset, value,
+ kFullWriteBarrier);
}
@@ -267,21 +352,57 @@ Node* InterpreterAssembler::LoadTypeFeedbackVector() {
}
+Node* InterpreterAssembler::CallConstruct(Node* original_constructor,
+ Node* constructor, Node* first_arg,
+ Node* arg_count) {
+ Callable callable = CodeFactory::InterpreterPushArgsAndConstruct(isolate());
+ CallDescriptor* descriptor = Linkage::GetStubCallDescriptor(
+ isolate(), zone(), callable.descriptor(), 0, CallDescriptor::kNoFlags);
+
+ Node* code_target = HeapConstant(callable.code());
+
+ Node** args = zone()->NewArray<Node*>(5);
+ args[0] = arg_count;
+ args[1] = original_constructor;
+ args[2] = constructor;
+ args[3] = first_arg;
+ args[4] = GetContext();
+
+ return CallN(descriptor, code_target, args);
+}
+
+
+Node* InterpreterAssembler::CallN(CallDescriptor* descriptor, Node* code_target,
+ Node** args) {
+ Node* stack_pointer_before_call = nullptr;
+ if (FLAG_debug_code) {
+ stack_pointer_before_call = raw_assembler_->LoadStackPointer();
+ }
+ Node* return_val = raw_assembler_->CallN(descriptor, code_target, args);
+ if (FLAG_debug_code) {
+ Node* stack_pointer_after_call = raw_assembler_->LoadStackPointer();
+ AbortIfWordNotEqual(stack_pointer_before_call, stack_pointer_after_call,
+ kUnexpectedStackPointer);
+ }
+ return return_val;
+}
+
+
Node* InterpreterAssembler::CallJS(Node* function, Node* first_arg,
Node* arg_count) {
- Callable builtin = CodeFactory::PushArgsAndCall(isolate());
+ Callable callable = CodeFactory::InterpreterPushArgsAndCall(isolate());
CallDescriptor* descriptor = Linkage::GetStubCallDescriptor(
- isolate(), zone(), builtin.descriptor(), 0, CallDescriptor::kNoFlags);
+ isolate(), zone(), callable.descriptor(), 0, CallDescriptor::kNoFlags);
- Node* code_target = HeapConstant(builtin.code());
+ Node* code_target = HeapConstant(callable.code());
Node** args = zone()->NewArray<Node*>(4);
args[0] = arg_count;
args[1] = first_arg;
args[2] = function;
- args[3] = ContextTaggedPointer();
+ args[3] = GetContext();
- return raw_assembler_->CallN(descriptor, code_target, args);
+ return CallN(descriptor, code_target, args);
}
@@ -289,7 +410,19 @@ Node* InterpreterAssembler::CallIC(CallInterfaceDescriptor descriptor,
Node* target, Node** args) {
CallDescriptor* call_descriptor = Linkage::GetStubCallDescriptor(
isolate(), zone(), descriptor, 0, CallDescriptor::kNoFlags);
- return raw_assembler_->CallN(call_descriptor, target, args);
+ return CallN(call_descriptor, target, args);
+}
+
+
+Node* InterpreterAssembler::CallIC(CallInterfaceDescriptor descriptor,
+ Node* target, Node* arg1, Node* arg2,
+ Node* arg3) {
+ Node** args = zone()->NewArray<Node*>(4);
+ args[0] = arg1;
+ args[1] = arg2;
+ args[2] = arg3;
+ args[3] = GetContext();
+ return CallIC(descriptor, target, args);
}
@@ -301,7 +434,7 @@ Node* InterpreterAssembler::CallIC(CallInterfaceDescriptor descriptor,
args[1] = arg2;
args[2] = arg3;
args[3] = arg4;
- args[4] = ContextTaggedPointer();
+ args[4] = GetContext();
return CallIC(descriptor, target, args);
}
@@ -315,22 +448,55 @@ Node* InterpreterAssembler::CallIC(CallInterfaceDescriptor descriptor,
args[2] = arg3;
args[3] = arg4;
args[4] = arg5;
- args[5] = ContextTaggedPointer();
+ args[5] = GetContext();
return CallIC(descriptor, target, args);
}
+Node* InterpreterAssembler::CallRuntime(Node* function_id, Node* first_arg,
+ Node* arg_count) {
+ Callable callable = CodeFactory::InterpreterCEntry(isolate());
+ CallDescriptor* descriptor = Linkage::GetStubCallDescriptor(
+ isolate(), zone(), callable.descriptor(), 0, CallDescriptor::kNoFlags);
+
+ Node* code_target = HeapConstant(callable.code());
+
+ // Get the function entry from the function id.
+ Node* function_table = raw_assembler_->ExternalConstant(
+ ExternalReference::runtime_function_table_address(isolate()));
+ 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** args = zone()->NewArray<Node*>(4);
+ args[0] = arg_count;
+ args[1] = first_arg;
+ args[2] = function_entry;
+ args[3] = GetContext();
+
+ return CallN(descriptor, code_target, args);
+}
+
+
Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id,
Node* arg1) {
- return raw_assembler_->CallRuntime1(function_id, arg1,
- ContextTaggedPointer());
+ return raw_assembler_->CallRuntime1(function_id, arg1, GetContext());
}
Node* InterpreterAssembler::CallRuntime(Runtime::FunctionId function_id,
Node* arg1, Node* arg2) {
- return raw_assembler_->CallRuntime2(function_id, arg1, arg2,
- ContextTaggedPointer());
+ return raw_assembler_->CallRuntime2(function_id, arg1, arg2, GetContext());
+}
+
+
+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());
}
@@ -349,7 +515,7 @@ void InterpreterAssembler::Return() {
BytecodeOffset(),
BytecodeArrayTaggedPointer(),
DispatchTableRawPointer(),
- ContextTaggedPointer() };
+ GetContext() };
Node* tail_call = raw_assembler_->TailCallN(
call_descriptor(), exit_trampoline_code_object, args);
// This should always be the end node.
@@ -409,7 +575,7 @@ void InterpreterAssembler::DispatchTo(Node* new_bytecode_offset) {
new_bytecode_offset,
BytecodeArrayTaggedPointer(),
DispatchTableRawPointer(),
- ContextTaggedPointer() };
+ GetContext() };
Node* tail_call =
raw_assembler_->TailCallN(call_descriptor(), target_code_object, args);
// This should always be the end node.
@@ -417,6 +583,24 @@ 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();
+}
+
+
+void InterpreterAssembler::AbortIfWordNotEqual(Node* lhs, Node* rhs,
+ BailoutReason bailout_reason) {
+ RawMachineAssembler::Label match, no_match;
+ Node* condition = raw_assembler_->WordEqual(lhs, rhs);
+ raw_assembler_->Branch(condition, &match, &no_match);
+ raw_assembler_->Bind(&no_match);
+ Abort(bailout_reason);
+ raw_assembler_->Bind(&match);
+}
+
+
void InterpreterAssembler::AddEndInput(Node* input) {
DCHECK_NOT_NULL(input);
end_nodes_.push_back(input);
@@ -432,6 +616,20 @@ void InterpreterAssembler::End() {
}
+// static
+bool InterpreterAssembler::TargetSupportsUnalignedAccess() {
+#if V8_TARGET_ARCH_MIPS || V8_TARGET_ARCH_MIPS64
+ return false;
+#elif V8_TARGET_ARCH_ARM || V8_TARGET_ARCH_ARM64 || V8_TARGET_ARCH_PPC
+ return CpuFeatures::IsSupported(UNALIGNED_ACCESSES);
+#elif V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_X87
+ return true;
+#else
+#error "Unknown Architecture"
+#endif
+}
+
+
// RawMachineAssembler delegate helpers:
Isolate* InterpreterAssembler::isolate() { return raw_assembler_->isolate(); }
@@ -452,6 +650,6 @@ Schedule* InterpreterAssembler::schedule() {
Zone* InterpreterAssembler::zone() { return raw_assembler_->zone(); }
-} // namespace interpreter
+} // namespace compiler
} // namespace internal
} // namespace v8