Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(641)

Unified Diff: src/interpreter/interpreter-assembler.cc

Issue 1783483002: [interpreter] Add support for scalable operands. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Operand renaming. Created 4 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: src/interpreter/interpreter-assembler.cc
diff --git a/src/interpreter/interpreter-assembler.cc b/src/interpreter/interpreter-assembler.cc
index 5d9929e3ae49e2f0f6d8586d3a38a1cf27007227..03bb5e810d6c3f57dec311e9c5681f1dff2be6e2 100644
--- a/src/interpreter/interpreter-assembler.cc
+++ b/src/interpreter/interpreter-assembler.cc
@@ -22,12 +22,34 @@ namespace interpreter {
using compiler::Node;
InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone,
- Bytecode bytecode)
+ Bytecode bytecode, int 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),
+ context_(this, MachineRepresentation::kTagged),
+ bytecode_array_(this, MachineRepresentation::kTagged),
+ disable_stack_check_across_call_(false),
+ stack_pointer_before_call_(nullptr) {
+ accumulator_.Bind(
+ Parameter(InterpreterDispatchDescriptor::kAccumulatorParameter));
+ context_.Bind(Parameter(InterpreterDispatchDescriptor::kContextParameter));
+ bytecode_array_.Bind(
+ Parameter(InterpreterDispatchDescriptor::kBytecodeArrayParameter));
+ if (FLAG_trace_ignition) {
+ TraceBytecode(Runtime::kInterpreterTraceBytecodeEntry);
+ }
+}
+
+InterpreterAssembler::InterpreterAssembler(Isolate* isolate, Zone* zone)
+ : compiler::CodeStubAssembler(
+ isolate, zone, InterpreterDispatchDescriptor(isolate),
+ Code::ComputeFlags(Code::STUB), "InvalidBytecode", 0),
+ bytecode_(static_cast<Bytecode>(-1)),
+ operand_scale_(-1),
accumulator_(this, MachineRepresentation::kTagged),
context_(this, MachineRepresentation::kTagged),
bytecode_array_(this, MachineRepresentation::kTagged),
@@ -119,22 +141,22 @@ Node* InterpreterAssembler::NextRegister(Node* reg_index) {
Node* InterpreterAssembler::BytecodeOperand(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(), IntPtrConstant(Bytecodes::GetOperandOffset(
- bytecode_, operand_index))));
+ DCHECK_EQ(OperandSize::kByte, Bytecodes::GetOperandSize(
+ bytecode_, operand_index, operand_scale()));
+ return Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(),
+ IntPtrAdd(BytecodeOffset(),
+ IntPtrConstant(Bytecodes::GetOperandOffset(
+ bytecode_, operand_index, operand_scale()))));
}
Node* InterpreterAssembler::BytecodeOperandSignExtended(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(), IntPtrConstant(Bytecodes::GetOperandOffset(
- bytecode_, operand_index))));
+ DCHECK_EQ(OperandSize::kByte, Bytecodes::GetOperandSize(
+ bytecode_, operand_index, operand_scale()));
+ Node* load = Load(MachineType::Int8(), BytecodeArrayTaggedPointer(),
+ IntPtrAdd(BytecodeOffset(),
+ IntPtrConstant(Bytecodes::GetOperandOffset(
+ bytecode_, operand_index, operand_scale()))));
// Ensure that we sign extend to full pointer size
if (kPointerSize == 8) {
load = ChangeInt32ToInt64(load);
@@ -144,15 +166,17 @@ Node* InterpreterAssembler::BytecodeOperandSignExtended(int operand_index) {
Node* InterpreterAssembler::BytecodeOperandShort(int operand_index) {
DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode_));
- DCHECK_EQ(OperandSize::kShort,
- Bytecodes::GetOperandSize(bytecode_, operand_index));
+ DCHECK_EQ(
+ OperandSize::kShort,
+ Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale()));
if (TargetSupportsUnalignedAccess()) {
- return Load(
- MachineType::Uint16(), BytecodeArrayTaggedPointer(),
- IntPtrAdd(BytecodeOffset(), IntPtrConstant(Bytecodes::GetOperandOffset(
- bytecode_, operand_index))));
+ return Load(MachineType::Uint16(), BytecodeArrayTaggedPointer(),
+ IntPtrAdd(BytecodeOffset(),
+ IntPtrConstant(Bytecodes::GetOperandOffset(
+ bytecode_, operand_index, operand_scale()))));
} else {
- int offset = Bytecodes::GetOperandOffset(bytecode_, operand_index);
+ int offset =
+ Bytecodes::GetOperandOffset(bytecode_, operand_index, operand_scale());
Node* first_byte =
Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(),
IntPtrAdd(BytecodeOffset(), IntPtrConstant(offset)));
@@ -160,9 +184,11 @@ Node* InterpreterAssembler::BytecodeOperandShort(int operand_index) {
Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(),
IntPtrAdd(BytecodeOffset(), IntPtrConstant(offset + 1)));
#if V8_TARGET_LITTLE_ENDIAN
- return WordOr(WordShl(second_byte, kBitsPerByte), first_byte);
+ return WordOr(WordShl(second_byte, IntPtrConstant(kBitsPerByte)),
+ first_byte);
#elif V8_TARGET_BIG_ENDIAN
- return WordOr(WordShl(first_byte, kBitsPerByte), second_byte);
+ return WordOr(WordShl(first_byte, IntPtrConstant(kBitsPerByte)),
+ second_byte);
#else
#error "Unknown Architecture"
#endif
@@ -172,9 +198,11 @@ Node* InterpreterAssembler::BytecodeOperandShort(int operand_index) {
Node* InterpreterAssembler::BytecodeOperandShortSignExtended(
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());
Node* load;
if (TargetSupportsUnalignedAccess()) {
load = Load(MachineType::Int16(), BytecodeArrayTaggedPointer(),
@@ -204,16 +232,109 @@ Node* InterpreterAssembler::BytecodeOperandShortSignExtended(
return load;
}
+Node* InterpreterAssembler::BytecodeOperandQuad(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 {
+ Node* bytes[4];
+ for (int i = 0; i < static_cast<int>(arraysize(bytes)); ++i) {
+ bytes[i] =
+ Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(),
+ IntPtrAdd(BytecodeOffset(), IntPtrConstant(operand_offset + i)));
+ }
+#if V8_TARGET_LITTLE_ENDIAN
+ Node* upper =
+ WordOr(WordShl(bytes[3], IntPtrConstant(kBitsPerByte)), bytes[2]);
+ Node* lower =
+ WordOr(WordShl(bytes[1], IntPtrConstant(kBitsPerByte)), bytes[0]);
+ return WordOr(WordShl(upper, IntPtrConstant(2 * kBitsPerByte)), lower);
+#elif V8_TARGET_BIG_ENDIAN
+ Node* upper =
+ WordOr(WordShl(bytes[0], IntPtrConstant(kBitsPerByte)), bytes[1]);
+ Node* lower =
+ WordOr(WordShl(bytes[2], IntPtrConstant(kBitsPerByte)), bytes[3]);
+ return WordOr(WordShl(upper, IntPtrConstant(2 * kBitsPerByte)), lower);
+#else
+#error "Unknown Architecture"
+#endif
+ }
+}
+
+Node* InterpreterAssembler::BytecodeOperandQuadSignExtended(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 {
+ Node* bytes[4];
+ for (int i = 0; i < static_cast<int>(arraysize(bytes)); ++i) {
+ bytes[i] =
+ Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(),
+ IntPtrAdd(BytecodeOffset(), IntPtrConstant(operand_offset + i)));
+ }
+#if V8_TARGET_LITTLE_ENDIAN
+ Node* upper =
+ WordOr(WordShl(bytes[3], IntPtrConstant(kBitsPerByte)), bytes[2]);
+ Node* lower =
+ WordOr(WordShl(bytes[1], IntPtrConstant(kBitsPerByte)), bytes[0]);
+ load = WordOr(WordShl(upper, IntPtrConstant(2 * kBitsPerByte)), lower);
+#elif V8_TARGET_BIG_ENDIAN
+ Node* upper =
+ WordOr(WordShl(bytes[0], IntPtrConstant(kBitsPerByte)), bytes[1]);
+ Node* lower =
+ WordOr(WordShl(bytes[2], IntPtrConstant(kBitsPerByte)), bytes[3]);
+ load = WordOr(WordShl(upper, IntPtrConstant(2 * kBitsPerByte)), lower);
+#else
+#error "Unknown Architecture"
+#endif
+ }
+
+ // Ensure that we sign extend to full pointer size
+ if (kPointerSize == 8) {
+ load = ChangeInt32ToInt64(load);
+ }
+ return load;
+}
+
Node* InterpreterAssembler::BytecodeOperandCount(int operand_index) {
- switch (Bytecodes::GetOperandSize(bytecode_, operand_index)) {
+ DCHECK_EQ(OperandType::kRegCount8,
+ Bytecodes::GetOperandType(bytecode_, operand_index));
+ OperandSize operand_size =
+ Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale());
+ switch (operand_size) {
case OperandSize::kByte:
- DCHECK_EQ(OperandType::kRegCount8,
- Bytecodes::GetOperandType(bytecode_, operand_index));
return BytecodeOperand(operand_index);
case OperandSize::kShort:
- DCHECK_EQ(OperandType::kRegCount16,
- Bytecodes::GetOperandType(bytecode_, operand_index));
return BytecodeOperandShort(operand_index);
+ case OperandSize::kQuad:
+ return BytecodeOperandQuad(operand_index);
+ case OperandSize::kNone:
+ UNREACHABLE();
+ }
+ return nullptr;
+}
+
+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());
+ switch (operand_size) {
+ case OperandSize::kByte:
+ return BytecodeOperand(operand_index);
+ case OperandSize::kShort:
+ case OperandSize::kQuad:
case OperandSize::kNone:
UNREACHABLE();
}
@@ -223,19 +344,35 @@ Node* InterpreterAssembler::BytecodeOperandCount(int operand_index) {
Node* InterpreterAssembler::BytecodeOperandImm(int operand_index) {
DCHECK_EQ(OperandType::kImm8,
Bytecodes::GetOperandType(bytecode_, operand_index));
- return BytecodeOperandSignExtended(operand_index);
+ OperandSize operand_size =
+ Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale());
+ switch (operand_size) {
+ case OperandSize::kByte:
+ return BytecodeOperandSignExtended(operand_index);
+ case OperandSize::kShort:
+ return BytecodeOperandShortSignExtended(operand_index);
+ case OperandSize::kQuad:
+ return BytecodeOperandQuadSignExtended(operand_index);
+ case OperandSize::kNone:
+ UNREACHABLE();
+ }
+ return nullptr;
}
Node* InterpreterAssembler::BytecodeOperandIdx(int operand_index) {
- switch (Bytecodes::GetOperandSize(bytecode_, operand_index)) {
+ DCHECK(OperandType::kIdx8 ==
+ Bytecodes::GetOperandType(bytecode_, operand_index) ||
+ OperandType::kRuntimeId ==
+ Bytecodes::GetOperandType(bytecode_, operand_index));
+ OperandSize operand_size =
+ Bytecodes::GetOperandSize(bytecode_, operand_index, operand_scale());
+ switch (operand_size) {
case OperandSize::kByte:
- DCHECK_EQ(OperandType::kIdx8,
- Bytecodes::GetOperandType(bytecode_, operand_index));
return BytecodeOperand(operand_index);
case OperandSize::kShort:
- DCHECK_EQ(OperandType::kIdx16,
- Bytecodes::GetOperandType(bytecode_, operand_index));
return BytecodeOperandShort(operand_index);
+ case OperandSize::kQuad:
+ return BytecodeOperandQuad(operand_index);
case OperandSize::kNone:
UNREACHABLE();
}
@@ -245,15 +382,17 @@ Node* InterpreterAssembler::BytecodeOperandIdx(int operand_index) {
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) {
+ DCHECK(Bytecodes::IsRegisterOperandType(operand_type));
+ switch (Bytecodes::SizeOfOperand(operand_type, operand_scale())) {
+ case OperandSize::kByte:
return BytecodeOperandSignExtended(operand_index);
- } else if (operand_size == OperandSize::kShort) {
+ case OperandSize::kShort:
return BytecodeOperandShortSignExtended(operand_index);
- }
+ case OperandSize::kQuad:
+ return BytecodeOperandQuadSignExtended(operand_index);
+ case OperandSize::kNone:
+ UNREACHABLE();
}
- UNREACHABLE();
return nullptr;
}
@@ -432,7 +571,8 @@ void InterpreterAssembler::JumpIfWordNotEqual(Node* lhs, Node* rhs,
}
void InterpreterAssembler::Dispatch() {
- DispatchTo(Advance(Bytecodes::Size(bytecode_)));
+ DCHECK(base::bits::IsPowerOfTwo32(operand_scale_));
+ DispatchTo(Advance(Bytecodes::Size(bytecode_, operand_scale_)));
}
void InterpreterAssembler::DispatchTo(Node* new_bytecode_offset) {
@@ -464,6 +604,23 @@ void InterpreterAssembler::DispatchToBytecodeHandler(Node* handler,
TailCall(descriptor, handler, args, 0);
}
+void InterpreterAssembler::RedispatchWide() {
+ STATIC_ASSERT(static_cast<int>(Bytecode::kExtraWide) ==
+ static_cast<int>(Bytecode::kWide) + 1);
+ Node* upper = Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(),
+ BytecodeOffset());
+ upper =
+ IntPtrAdd(upper, Int32Constant(-static_cast<int>(Bytecode::kWide) + 1));
+ Node* lower = Load(MachineType::Uint8(), BytecodeArrayTaggedPointer(),
+ IntPtrAdd(BytecodeOffset(), Int32Constant(1)));
+ Node* target_bytecode =
+ Word32Or(Word32Shl(upper, Int32Constant(kBitsPerByte)), lower);
+ Node* target_code_object =
+ Load(MachineType::Pointer(), DispatchTableRawPointer(),
+ Word32Shl(target_bytecode, Int32Constant(kPointerSizeLog2)));
+ DispatchToBytecodeHandler(target_code_object, Advance(1));
+}
+
void InterpreterAssembler::InterpreterReturn() {
// TODO(rmcilroy): Investigate whether it is worth supporting self
// optimization of primitive functions like FullCodegen.

Powered by Google App Engine
This is Rietveld 408576698