summaryrefslogtreecommitdiff
path: root/deps/v8/src/interpreter/interpreter-assembler.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/interpreter/interpreter-assembler.cc')
-rw-r--r--deps/v8/src/interpreter/interpreter-assembler.cc386
1 files changed, 266 insertions, 120 deletions
diff --git a/deps/v8/src/interpreter/interpreter-assembler.cc b/deps/v8/src/interpreter/interpreter-assembler.cc
index 440e879c48..2663e4a876 100644
--- a/deps/v8/src/interpreter/interpreter-assembler.cc
+++ b/deps/v8/src/interpreter/interpreter-assembler.cc
@@ -22,12 +22,16 @@ namespace interpreter {
using compiler::Node;
InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone,
- Bytecode bytecode)
- : compiler::CodeStubAssembler(
- isolate, zone, InterpreterDispatchDescriptor(isolate),
- Code::ComputeFlags(Code::STUB), Bytecodes::ToString(bytecode), 0),
+ Bytecode bytecode,
+ OperandScale operand_scale)
+ : compiler::CodeStubAssembler(isolate, zone,
+ InterpreterDispatchDescriptor(isolate),
+ Code::ComputeFlags(Code::BYTECODE_HANDLER),
+ Bytecodes::ToString(bytecode), 0),
bytecode_(bytecode),
+ operand_scale_(operand_scale),
accumulator_(this, MachineRepresentation::kTagged),
+ accumulator_use_(AccumulatorUse::kNone),
context_(this, MachineRepresentation::kTagged),
bytecode_array_(this, MachineRepresentation::kTagged),
disable_stack_check_across_call_(false),
@@ -42,11 +46,26 @@ InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone,
}
}
-InterpreterAssembler::~InterpreterAssembler() {}
+InterpreterAssembler::~InterpreterAssembler() {
+ // If the following check fails the handler does not use the
+ // accumulator in the way described in the bytecode definitions in
+ // bytecodes.h.
+ DCHECK_EQ(accumulator_use_, Bytecodes::GetAccumulatorUse(bytecode_));
+}
+
+Node* InterpreterAssembler::GetAccumulatorUnchecked() {
+ return accumulator_.value();
+}
-Node* InterpreterAssembler::GetAccumulator() { return accumulator_.value(); }
+Node* InterpreterAssembler::GetAccumulator() {
+ DCHECK(Bytecodes::ReadsAccumulator(bytecode_));
+ accumulator_use_ = accumulator_use_ | AccumulatorUse::kRead;
+ return GetAccumulatorUnchecked();
+}
void InterpreterAssembler::SetAccumulator(Node* value) {
+ DCHECK(Bytecodes::WritesAccumulator(bytecode_));
+ accumulator_use_ = accumulator_use_ | AccumulatorUse::kWrite;
accumulator_.Bind(value);
}
@@ -79,11 +98,11 @@ Node* InterpreterAssembler::RegisterLocation(Node* reg_index) {
Node* InterpreterAssembler::LoadRegister(int offset) {
return Load(MachineType::AnyTagged(), RegisterFileRawPointer(),
- Int32Constant(offset));
+ IntPtrConstant(offset));
}
Node* InterpreterAssembler::LoadRegister(Register reg) {
- return LoadRegister(reg.ToOperand() << kPointerSizeLog2);
+ return LoadRegister(IntPtrConstant(-reg.index()));
}
Node* InterpreterAssembler::RegisterFrameOffset(Node* index) {
@@ -97,12 +116,12 @@ Node* InterpreterAssembler::LoadRegister(Node* reg_index) {
Node* InterpreterAssembler::StoreRegister(Node* value, int offset) {
return StoreNoWriteBarrier(MachineRepresentation::kTagged,
- RegisterFileRawPointer(), Int32Constant(offset),
+ RegisterFileRawPointer(), IntPtrConstant(offset),
value);
}
Node* InterpreterAssembler::StoreRegister(Node* value, Register reg) {
- return StoreRegister(value, reg.ToOperand() << kPointerSizeLog2);
+ return StoreRegister(value, IntPtrConstant(-reg.index()));
}
Node* InterpreterAssembler::StoreRegister(Node* value, Node* reg_index) {
@@ -113,27 +132,31 @@ Node* InterpreterAssembler::StoreRegister(Node* value, Node* reg_index) {
Node* InterpreterAssembler::NextRegister(Node* reg_index) {
// Register indexes are negative, so the next index is minus one.
- return IntPtrAdd(reg_index, Int32Constant(-1));
+ return IntPtrAdd(reg_index, IntPtrConstant(-1));
+}
+
+Node* InterpreterAssembler::OperandOffset(int operand_index) {
+ return IntPtrConstant(
+ Bytecodes::GetOperandOffset(bytecode_, operand_index, operand_scale()));
}
-Node* InterpreterAssembler::BytecodeOperand(int operand_index) {
+Node* InterpreterAssembler::BytecodeOperandUnsignedByte(int operand_index) {
DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_));
- DCHECK_EQ(OperandSize::kByte,
- Bytecodes::GetOperandSize(bytecode_, operand_index));
- return Load(
- MachineType::Uint8(), BytecodeArrayTaggedPointer(),
- IntPtrAdd(BytecodeOffset(), Int32Constant(Bytecodes::GetOperandOffset(
- bytecode_, operand_index))));
+ DCHECK_EQ(OperandSize::kByte, Bytecodes::GetOperandSize(
+ bytecode_, operand_index, operand_scale()));
+ Node* operand_offset = OperandOffset(operand_index);
+ return Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(),
+ IntPtrAdd(BytecodeOffset(), operand_offset));
}
-Node* InterpreterAssembler::BytecodeOperandSignExtended(int operand_index) {
+Node* InterpreterAssembler::BytecodeOperandSignedByte(int operand_index) {
DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_));
- DCHECK_EQ(OperandSize::kByte,
- Bytecodes::GetOperandSize(bytecode_, operand_index));
- Node* load = Load(
- MachineType::Int8(), BytecodeArrayTaggedPointer(),
- IntPtrAdd(BytecodeOffset(), Int32Constant(Bytecodes::GetOperandOffset(
- bytecode_, operand_index))));
+ DCHECK_EQ(OperandSize::kByte, Bytecodes::GetOperandSize(
+ bytecode_, operand_index, operand_scale()));
+ Node* operand_offset = OperandOffset(operand_index);
+ Node* load = Load(MachineType::Int8(), BytecodeArrayTaggedPointer(),
+ IntPtrAdd(BytecodeOffset(), operand_offset));
+
// Ensure that we sign extend to full pointer size
if (kPointerSize == 8) {
load = ChangeInt32ToInt64(load);
@@ -141,58 +164,85 @@ Node* InterpreterAssembler::BytecodeOperandSignExtended(int operand_index) {
return load;
}
-Node* InterpreterAssembler::BytecodeOperandShort(int operand_index) {
- DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_));
- DCHECK_EQ(OperandSize::kShort,
- Bytecodes::GetOperandSize(bytecode_, operand_index));
- if (TargetSupportsUnalignedAccess()) {
- return Load(
- MachineType::Uint16(), BytecodeArrayTaggedPointer(),
- IntPtrAdd(BytecodeOffset(), Int32Constant(Bytecodes::GetOperandOffset(
- bytecode_, operand_index))));
- } else {
- int offset = Bytecodes::GetOperandOffset(bytecode_, operand_index);
- Node* first_byte = Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(),
- IntPtrAdd(BytecodeOffset(), Int32Constant(offset)));
- Node* second_byte =
- Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(),
- IntPtrAdd(BytecodeOffset(), Int32Constant(offset + 1)));
+compiler::Node* InterpreterAssembler::BytecodeOperandReadUnaligned(
+ int relative_offset, MachineType result_type) {
+ static const int kMaxCount = 4;
+ DCHECK(!TargetSupportsUnalignedAccess());
+
+ int count;
+ switch (result_type.representation()) {
+ case MachineRepresentation::kWord16:
+ count = 2;
+ break;
+ case MachineRepresentation::kWord32:
+ count = 4;
+ break;
+ default:
+ UNREACHABLE();
+ break;
+ }
+ MachineType msb_type =
+ result_type.IsSigned() ? MachineType::Int8() : MachineType::Uint8();
+
#if V8_TARGET_LITTLE_ENDIAN
- return WordOr(WordShl(second_byte, kBitsPerByte), first_byte);
+ const int kStep = -1;
+ int msb_offset = count - 1;
#elif V8_TARGET_BIG_ENDIAN
- return WordOr(WordShl(first_byte, kBitsPerByte), second_byte);
+ const int kStep = 1;
+ int msb_offset = 0;
#else
#error "Unknown Architecture"
#endif
+
+ // Read the most signicant bytecode into bytes[0] and then in order
+ // down to least significant in bytes[count - 1].
+ DCHECK(count <= kMaxCount);
+ compiler::Node* bytes[kMaxCount];
+ for (int i = 0; i < count; i++) {
+ MachineType machine_type = (i == 0) ? msb_type : MachineType::Uint8();
+ Node* offset = IntPtrConstant(relative_offset + msb_offset + i * kStep);
+ Node* array_offset = IntPtrAdd(BytecodeOffset(), offset);
+ bytes[i] = Load(machine_type, BytecodeArrayTaggedPointer(), array_offset);
+ }
+
+ // Pack LSB to MSB.
+ Node* result = bytes[--count];
+ for (int i = 1; --count >= 0; i++) {
+ Node* shift = Int32Constant(i * kBitsPerByte);
+ Node* value = Word32Shl(bytes[count], shift);
+ result = Word32Or(value, result);
}
+ return result;
}
-Node* InterpreterAssembler::BytecodeOperandShortSignExtended(
- int operand_index) {
+Node* InterpreterAssembler::BytecodeOperandUnsignedShort(int operand_index) {
DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_));
- DCHECK_EQ(OperandSize::kShort,
- Bytecodes::GetOperandSize(bytecode_, operand_index));
- int operand_offset = Bytecodes::GetOperandOffset(bytecode_, operand_index);
+ DCHECK_EQ(
+ OperandSize::kShort,
+ Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale()));
+ int operand_offset =
+ Bytecodes::GetOperandOffset(bytecode_, operand_index, operand_scale());
+ if (TargetSupportsUnalignedAccess()) {
+ return Load(MachineType::Uint16(), BytecodeArrayTaggedPointer(),
+ IntPtrAdd(BytecodeOffset(), IntPtrConstant(operand_offset)));
+ } else {
+ return BytecodeOperandReadUnaligned(operand_offset, MachineType::Uint16());
+ }
+}
+
+Node* InterpreterAssembler::BytecodeOperandSignedShort(int operand_index) {
+ DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_));
+ DCHECK_EQ(
+ OperandSize::kShort,
+ Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale()));
+ int operand_offset =
+ Bytecodes::GetOperandOffset(bytecode_, operand_index, operand_scale());
Node* load;
if (TargetSupportsUnalignedAccess()) {
load = Load(MachineType::Int16(), BytecodeArrayTaggedPointer(),
- IntPtrAdd(BytecodeOffset(), Int32Constant(operand_offset)));
+ IntPtrAdd(BytecodeOffset(), IntPtrConstant(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 = Load(MachineType::Int8(), BytecodeArrayTaggedPointer(),
- IntPtrAdd(BytecodeOffset(), hi_byte_offset));
- Node* lo_byte = Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(),
- IntPtrAdd(BytecodeOffset(), lo_byte_offset));
- hi_byte = Word32Shl(hi_byte, Int32Constant(kBitsPerByte));
- load = Word32Or(hi_byte, lo_byte);
+ load = BytecodeOperandReadUnaligned(operand_offset, MachineType::Int16());
}
// Ensure that we sign extend to full pointer size
@@ -202,57 +252,123 @@ Node* InterpreterAssembler::BytecodeOperandShortSignExtended(
return load;
}
-Node* InterpreterAssembler::BytecodeOperandCount(int operand_index) {
- switch (Bytecodes::GetOperandSize(bytecode_, operand_index)) {
+Node* InterpreterAssembler::BytecodeOperandUnsignedQuad(int operand_index) {
+ DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_));
+ DCHECK_EQ(OperandSize::kQuad, Bytecodes::GetOperandSize(
+ bytecode_, operand_index, operand_scale()));
+ int operand_offset =
+ Bytecodes::GetOperandOffset(bytecode_, operand_index, operand_scale());
+ if (TargetSupportsUnalignedAccess()) {
+ return Load(MachineType::Uint32(), BytecodeArrayTaggedPointer(),
+ IntPtrAdd(BytecodeOffset(), IntPtrConstant(operand_offset)));
+ } else {
+ return BytecodeOperandReadUnaligned(operand_offset, MachineType::Uint32());
+ }
+}
+
+Node* InterpreterAssembler::BytecodeOperandSignedQuad(int operand_index) {
+ DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_));
+ DCHECK_EQ(OperandSize::kQuad, Bytecodes::GetOperandSize(
+ bytecode_, operand_index, operand_scale()));
+ int operand_offset =
+ Bytecodes::GetOperandOffset(bytecode_, operand_index, operand_scale());
+ Node* load;
+ if (TargetSupportsUnalignedAccess()) {
+ load = Load(MachineType::Int32(), BytecodeArrayTaggedPointer(),
+ IntPtrAdd(BytecodeOffset(), IntPtrConstant(operand_offset)));
+ } else {
+ load = BytecodeOperandReadUnaligned(operand_offset, MachineType::Int32());
+ }
+
+ // Ensure that we sign extend to full pointer size
+ if (kPointerSize == 8) {
+ load = ChangeInt32ToInt64(load);
+ }
+ return load;
+}
+
+Node* InterpreterAssembler::BytecodeSignedOperand(int operand_index,
+ OperandSize operand_size) {
+ DCHECK(!Bytecodes::IsUnsignedOperandType(
+ Bytecodes::GetOperandType(bytecode_, operand_index)));
+ switch (operand_size) {
case OperandSize::kByte:
- DCHECK_EQ(OperandType::kRegCount8,
- Bytecodes::GetOperandType(bytecode_, operand_index));
- return BytecodeOperand(operand_index);
+ return BytecodeOperandSignedByte(operand_index);
case OperandSize::kShort:
- DCHECK_EQ(OperandType::kRegCount16,
- Bytecodes::GetOperandType(bytecode_, operand_index));
- return BytecodeOperandShort(operand_index);
+ return BytecodeOperandSignedShort(operand_index);
+ case OperandSize::kQuad:
+ return BytecodeOperandSignedQuad(operand_index);
case OperandSize::kNone:
UNREACHABLE();
}
return nullptr;
}
-Node* InterpreterAssembler::BytecodeOperandImm(int operand_index) {
- DCHECK_EQ(OperandType::kImm8,
- Bytecodes::GetOperandType(bytecode_, operand_index));
- return BytecodeOperandSignExtended(operand_index);
-}
-
-Node* InterpreterAssembler::BytecodeOperandIdx(int operand_index) {
- switch (Bytecodes::GetOperandSize(bytecode_, operand_index)) {
+Node* InterpreterAssembler::BytecodeUnsignedOperand(int operand_index,
+ OperandSize operand_size) {
+ DCHECK(Bytecodes::IsUnsignedOperandType(
+ Bytecodes::GetOperandType(bytecode_, operand_index)));
+ switch (operand_size) {
case OperandSize::kByte:
- DCHECK_EQ(OperandType::kIdx8,
- Bytecodes::GetOperandType(bytecode_, operand_index));
- return BytecodeOperand(operand_index);
+ return BytecodeOperandUnsignedByte(operand_index);
case OperandSize::kShort:
- DCHECK_EQ(OperandType::kIdx16,
- Bytecodes::GetOperandType(bytecode_, operand_index));
- return BytecodeOperandShort(operand_index);
+ return BytecodeOperandUnsignedShort(operand_index);
+ case OperandSize::kQuad:
+ return BytecodeOperandUnsignedQuad(operand_index);
case OperandSize::kNone:
UNREACHABLE();
}
return nullptr;
}
+Node* InterpreterAssembler::BytecodeOperandCount(int operand_index) {
+ DCHECK_EQ(OperandType::kRegCount,
+ Bytecodes::GetOperandType(bytecode_, operand_index));
+ OperandSize operand_size =
+ Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale());
+ return BytecodeUnsignedOperand(operand_index, operand_size);
+}
+
+Node* InterpreterAssembler::BytecodeOperandFlag(int operand_index) {
+ DCHECK_EQ(OperandType::kFlag8,
+ Bytecodes::GetOperandType(bytecode_, operand_index));
+ OperandSize operand_size =
+ Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale());
+ DCHECK_EQ(operand_size, OperandSize::kByte);
+ return BytecodeUnsignedOperand(operand_index, operand_size);
+}
+
+Node* InterpreterAssembler::BytecodeOperandImm(int operand_index) {
+ DCHECK_EQ(OperandType::kImm,
+ Bytecodes::GetOperandType(bytecode_, operand_index));
+ OperandSize operand_size =
+ Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale());
+ return BytecodeSignedOperand(operand_index, operand_size);
+}
+
+Node* InterpreterAssembler::BytecodeOperandIdx(int operand_index) {
+ DCHECK(OperandType::kIdx ==
+ Bytecodes::GetOperandType(bytecode_, operand_index));
+ OperandSize operand_size =
+ Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale());
+ return BytecodeUnsignedOperand(operand_index, operand_size);
+}
+
Node* InterpreterAssembler::BytecodeOperandReg(int operand_index) {
- OperandType operand_type =
- Bytecodes::GetOperandType(bytecode_, operand_index);
- if (Bytecodes::IsRegisterOperandType(operand_type)) {
- OperandSize operand_size = Bytecodes::SizeOfOperand(operand_type);
- if (operand_size == OperandSize::kByte) {
- return BytecodeOperandSignExtended(operand_index);
- } else if (operand_size == OperandSize::kShort) {
- return BytecodeOperandShortSignExtended(operand_index);
- }
- }
- UNREACHABLE();
- return nullptr;
+ DCHECK(Bytecodes::IsRegisterOperandType(
+ Bytecodes::GetOperandType(bytecode_, operand_index)));
+ OperandSize operand_size =
+ Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale());
+ return BytecodeSignedOperand(operand_index, operand_size);
+}
+
+Node* InterpreterAssembler::BytecodeOperandRuntimeId(int operand_index) {
+ DCHECK(OperandType::kRuntimeId ==
+ Bytecodes::GetOperandType(bytecode_, operand_index));
+ OperandSize operand_size =
+ Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale());
+ DCHECK_EQ(operand_size, OperandSize::kShort);
+ return BytecodeUnsignedOperand(operand_index, operand_size);
}
Node* InterpreterAssembler::LoadConstantPoolEntry(Node* index) {
@@ -264,14 +380,6 @@ Node* InterpreterAssembler::LoadConstantPoolEntry(Node* index) {
return Load(MachineType::AnyTagged(), constant_pool, entry_offset);
}
-Node* InterpreterAssembler::LoadFixedArrayElement(Node* fixed_array,
- int index) {
- Node* entry_offset =
- IntPtrAdd(IntPtrConstant(FixedArray::kHeaderSize - kHeapObjectTag),
- WordShl(Int32Constant(index), kPointerSizeLog2));
- return Load(MachineType::AnyTagged(), fixed_array, entry_offset);
-}
-
Node* InterpreterAssembler::LoadObjectField(Node* object, int offset) {
return Load(MachineType::AnyTagged(), object,
IntPtrConstant(offset - kHeapObjectTag));
@@ -285,7 +393,7 @@ Node* InterpreterAssembler::LoadContextSlot(Node* context, int slot_index) {
Node* InterpreterAssembler::LoadContextSlot(Node* context, Node* slot_index) {
Node* offset =
IntPtrAdd(WordShl(slot_index, kPointerSizeLog2),
- Int32Constant(Context::kHeaderSize - kHeapObjectTag));
+ IntPtrConstant(Context::kHeaderSize - kHeapObjectTag));
return Load(MachineType::AnyTagged(), context, offset);
}
@@ -293,7 +401,7 @@ Node* InterpreterAssembler::StoreContextSlot(Node* context, Node* slot_index,
Node* value) {
Node* offset =
IntPtrAdd(WordShl(slot_index, kPointerSizeLog2),
- Int32Constant(Context::kHeaderSize - kHeapObjectTag));
+ IntPtrConstant(Context::kHeaderSize - kHeapObjectTag));
return Store(MachineRepresentation::kTagged, context, offset, value);
}
@@ -311,8 +419,6 @@ Node* InterpreterAssembler::LoadTypeFeedbackVector() {
void InterpreterAssembler::CallPrologue() {
StoreRegister(SmiTag(BytecodeOffset()),
InterpreterFrameConstants::kBytecodeOffsetFromRegisterPointer);
- StoreRegister(BytecodeArrayTaggedPointer(),
- InterpreterFrameConstants::kBytecodeArrayFromRegisterPointer);
if (FLAG_debug_code && !disable_stack_check_across_call_) {
DCHECK(stack_pointer_before_call_ == nullptr);
@@ -368,7 +474,7 @@ Node* InterpreterAssembler::CallRuntimeN(Node* function_id, Node* context,
Node* function = IntPtrAdd(function_table, function_offset);
Node* function_entry =
Load(MachineType::Pointer(), function,
- Int32Constant(offsetof(Runtime::Function, entry)));
+ IntPtrConstant(offsetof(Runtime::Function, entry)));
return CallStub(callable.descriptor(), code_target, context, arg_count,
first_arg, function_entry, result_size);
@@ -405,7 +511,7 @@ void InterpreterAssembler::UpdateInterruptBudget(Node* weight) {
}
Node* InterpreterAssembler::Advance(int delta) {
- return IntPtrAdd(BytecodeOffset(), Int32Constant(delta));
+ return IntPtrAdd(BytecodeOffset(), IntPtrConstant(delta));
}
Node* InterpreterAssembler::Advance(Node* delta) {
@@ -438,18 +544,21 @@ void InterpreterAssembler::JumpIfWordNotEqual(Node* lhs, Node* rhs,
}
void InterpreterAssembler::Dispatch() {
- DispatchTo(Advance(Bytecodes::Size(bytecode_)));
+ DispatchTo(Advance(Bytecodes::Size(bytecode_, operand_scale_)));
}
void InterpreterAssembler::DispatchTo(Node* new_bytecode_offset) {
Node* target_bytecode = Load(
MachineType::Uint8(), BytecodeArrayTaggedPointer(), new_bytecode_offset);
+ if (kPointerSize == 8) {
+ target_bytecode = ChangeUint32ToUint64(target_bytecode);
+ }
// TODO(rmcilroy): Create a code target dispatch table to avoid conversion
// from code object on every dispatch.
Node* target_code_object =
Load(MachineType::Pointer(), DispatchTableRawPointer(),
- Word32Shl(target_bytecode, Int32Constant(kPointerSizeLog2)));
+ WordShl(target_bytecode, IntPtrConstant(kPointerSizeLog2)));
DispatchToBytecodeHandler(target_code_object, new_bytecode_offset);
}
@@ -461,12 +570,46 @@ void InterpreterAssembler::DispatchToBytecodeHandler(Node* handler,
}
InterpreterDispatchDescriptor descriptor(isolate());
- Node* args[] = {GetAccumulator(), RegisterFileRawPointer(),
+ Node* args[] = {GetAccumulatorUnchecked(), RegisterFileRawPointer(),
bytecode_offset, BytecodeArrayTaggedPointer(),
DispatchTableRawPointer(), GetContext()};
TailCall(descriptor, handler, args, 0);
}
+void InterpreterAssembler::DispatchWide(OperandScale operand_scale) {
+ // Dispatching a wide bytecode requires treating the prefix
+ // bytecode a base pointer into the dispatch table and dispatching
+ // the bytecode that follows relative to this base.
+ //
+ // Indices 0-255 correspond to bytecodes with operand_scale == 0
+ // Indices 256-511 correspond to bytecodes with operand_scale == 1
+ // Indices 512-767 correspond to bytecodes with operand_scale == 2
+ Node* next_bytecode_offset = Advance(1);
+ Node* next_bytecode = Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(),
+ next_bytecode_offset);
+ if (kPointerSize == 8) {
+ next_bytecode = ChangeUint32ToUint64(next_bytecode);
+ }
+ Node* base_index;
+ switch (operand_scale) {
+ case OperandScale::kDouble:
+ base_index = IntPtrConstant(1 << kBitsPerByte);
+ break;
+ case OperandScale::kQuadruple:
+ base_index = IntPtrConstant(2 << kBitsPerByte);
+ break;
+ default:
+ UNREACHABLE();
+ base_index = nullptr;
+ }
+ Node* target_index = IntPtrAdd(base_index, next_bytecode);
+ Node* target_code_object =
+ Load(MachineType::Pointer(), DispatchTableRawPointer(),
+ WordShl(target_index, kPointerSizeLog2));
+
+ DispatchToBytecodeHandler(target_code_object, next_bytecode_offset);
+}
+
void InterpreterAssembler::InterpreterReturn() {
// TODO(rmcilroy): Investigate whether it is worth supporting self
// optimization of primitive functions like FullCodegen.
@@ -505,27 +648,29 @@ void InterpreterAssembler::StackCheck() {
void InterpreterAssembler::Abort(BailoutReason bailout_reason) {
disable_stack_check_across_call_ = true;
Node* abort_id = SmiTag(Int32Constant(bailout_reason));
- Node* ret_value = CallRuntime(Runtime::kAbort, GetContext(), abort_id);
+ CallRuntime(Runtime::kAbort, GetContext(), abort_id);
disable_stack_check_across_call_ = false;
- // Unreached, but keeps turbofan happy.
- Return(ret_value);
}
void InterpreterAssembler::AbortIfWordNotEqual(Node* lhs, Node* rhs,
BailoutReason bailout_reason) {
CodeStubAssembler::Label match(this);
CodeStubAssembler::Label no_match(this);
+ CodeStubAssembler::Label end(this);
Node* condition = WordEqual(lhs, rhs);
Branch(condition, &match, &no_match);
Bind(&no_match);
Abort(bailout_reason);
+ Goto(&end);
Bind(&match);
+ Goto(&end);
+ Bind(&end);
}
void InterpreterAssembler::TraceBytecode(Runtime::FunctionId function_id) {
CallRuntime(function_id, GetContext(), BytecodeArrayTaggedPointer(),
- SmiTag(BytecodeOffset()), GetAccumulator());
+ SmiTag(BytecodeOffset()), GetAccumulatorUnchecked());
}
// static
@@ -534,7 +679,8 @@ bool InterpreterAssembler::TargetSupportsUnalignedAccess() {
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
+#elif V8_TARGET_ARCH_IA32 || V8_TARGET_ARCH_X64 || V8_TARGET_ARCH_X87 || \
+ V8_TARGET_ARCH_S390
return true;
#else
#error "Unknown Architecture"