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

Unified Diff: src/interpreter/bytecode-array-builder.cc

Issue 1783483002: [interpreter] Add support for scalable operands. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Fix tests. 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/bytecode-array-builder.cc
diff --git a/src/interpreter/bytecode-array-builder.cc b/src/interpreter/bytecode-array-builder.cc
index a99f0dae7e797f1e118d3f956683b547f684c899..858de311568b024ad6c068d77b9872ba3311e477 100644
--- a/src/interpreter/bytecode-array-builder.cc
+++ b/src/interpreter/bytecode-array-builder.cc
@@ -31,12 +31,20 @@ class BytecodeArrayBuilder::PreviousBytecodeHelper BASE_EMBEDDED {
MUST_USE_RESULT uint32_t GetOperand(int operand_index) const {
DCHECK_EQ(array_builder_.last_bytecode_start_, previous_bytecode_start_);
Bytecode bytecode = GetBytecode();
+ int prefix_offset = 0;
+ int operand_scale = Bytecodes::GetPrefixBytecodeScale(bytecode);
+ if (operand_scale > 1) {
+ prefix_offset = 1;
+ bytecode = Bytecodes::FromByte(array_builder_.bytecodes()->at(
+ previous_bytecode_start_ + prefix_offset));
+ }
DCHECK_GE(operand_index, 0);
DCHECK_LT(operand_index, Bytecodes::NumberOfOperands(bytecode));
size_t operand_offset =
- previous_bytecode_start_ +
- Bytecodes::GetOperandOffset(bytecode, operand_index);
- OperandSize size = Bytecodes::GetOperandSize(bytecode, operand_index);
+ previous_bytecode_start_ + prefix_offset +
+ Bytecodes::GetOperandOffset(bytecode, operand_index, operand_scale);
+ OperandSize size =
+ Bytecodes::GetOperandSize(bytecode, operand_index, operand_scale);
switch (size) {
case OperandSize::kNone:
UNREACHABLE();
@@ -44,11 +52,18 @@ class BytecodeArrayBuilder::PreviousBytecodeHelper BASE_EMBEDDED {
case OperandSize::kByte:
return static_cast<uint32_t>(
array_builder_.bytecodes()->at(operand_offset));
- case OperandSize::kShort:
+ case OperandSize::kShort: {
uint16_t operand =
(array_builder_.bytecodes()->at(operand_offset) << 8) +
array_builder_.bytecodes()->at(operand_offset + 1);
return static_cast<uint32_t>(operand);
+ }
+ case OperandSize::kQuad: {
+ return ((array_builder_.bytecodes()->at(operand_offset + 0) << 24) +
+ (array_builder_.bytecodes()->at(operand_offset + 1) << 16) +
+ (array_builder_.bytecodes()->at(operand_offset + 2) << 8) +
+ array_builder_.bytecodes()->at(operand_offset + 3));
+ }
}
return 0;
}
@@ -83,8 +98,7 @@ BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone,
parameter_count_(parameter_count),
local_register_count_(locals_count),
context_register_count_(context_count),
- temporary_allocator_(zone, fixed_register_count()),
- register_translator_(this) {
+ temporary_allocator_(zone, fixed_register_count()) {
DCHECK_GE(parameter_count_, 0);
DCHECK_GE(context_register_count_, 0);
DCHECK_GE(local_register_count_, 0);
@@ -125,8 +139,7 @@ Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() {
DCHECK(exit_seen_in_block_);
int bytecode_size = static_cast<int>(bytecodes_.size());
- int register_count =
- fixed_and_temporary_register_count() + translation_register_count();
+ int register_count = fixed_and_temporary_register_count();
int frame_size = register_count * kPointerSize;
Handle<FixedArray> constant_pool = constant_array_builder()->ToFixedArray();
Handle<FixedArray> handler_table = handler_table_builder()->ToHandlerTable();
@@ -146,26 +159,39 @@ Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() {
return bytecode_array;
}
-
template <size_t N>
-void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t(&operands)[N]) {
+void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t (&operands)[N],
+ int operand_scale) {
// Don't output dead code.
if (exit_seen_in_block_) return;
int operand_count = static_cast<int>(N);
DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), operand_count);
- int register_operand_count = Bytecodes::NumberOfRegisterOperands(bytecode);
- if (register_operand_count > 0) {
- register_translator()->TranslateInputRegisters(bytecode, operands,
- operand_count);
+ last_bytecode_start_ = bytecodes()->size();
+
+ // Emit prefix if scaling is active.
+ switch (operand_scale) {
+ case 4:
+ bytecodes()->push_back(Bytecodes::ToByte(Bytecode::kExtraWide));
+ break;
+ case 2:
+ bytecodes()->push_back(Bytecodes::ToByte(Bytecode::kWide));
+ break;
+ case 1:
+ break;
+ default:
+ UNREACHABLE();
+ break;
}
- last_bytecode_start_ = bytecodes()->size();
+ // Emit bytecode.
bytecodes()->push_back(Bytecodes::ToByte(bytecode));
+
+ // Emit operands.
for (int i = 0; i < operand_count; i++) {
- DCHECK(OperandIsValid(bytecode, i, operands[i]));
- switch (Bytecodes::GetOperandSize(bytecode, i)) {
+ DCHECK(OperandIsValid(bytecode, i, operand_scale, operands[i]));
+ switch (Bytecodes::GetOperandSize(bytecode, i, operand_scale)) {
case OperandSize::kNone:
UNREACHABLE();
break;
@@ -179,55 +205,57 @@ void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t(&operands)[N]) {
operand_bytes + 2);
break;
}
+ case OperandSize::kQuad: {
+ uint8_t operand_bytes[4];
+ WriteUnalignedUInt32(operand_bytes, operands[i]);
+ bytecodes()->insert(bytecodes()->end(), operand_bytes,
+ operand_bytes + 4);
+ break;
+ }
}
}
-
- if (register_operand_count > 0) {
- register_translator()->TranslateOutputRegisters();
- }
}
+void BytecodeArrayBuilder::Output(Bytecode bytecode) {
+ // Don't output dead code.
+ if (exit_seen_in_block_) return;
-void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0,
- uint32_t operand1, uint32_t operand2,
- uint32_t operand3) {
- uint32_t operands[] = {operand0, operand1, operand2, operand3};
- Output(bytecode, operands);
+ DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 0);
+ last_bytecode_start_ = bytecodes()->size();
+ bytecodes()->push_back(Bytecodes::ToByte(bytecode));
}
+void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, int operand_scale,
+ uint32_t operand0, uint32_t operand1,
+ uint32_t operand2, uint32_t operand3) {
+ uint32_t operands[] = {operand0, operand1, operand2, operand3};
+ Output(bytecode, operands, operand_scale);
+}
-void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0,
- uint32_t operand1, uint32_t operand2) {
+void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, int operand_scale,
+ uint32_t operand0, uint32_t operand1,
+ uint32_t operand2) {
uint32_t operands[] = {operand0, operand1, operand2};
- Output(bytecode, operands);
+ Output(bytecode, operands, operand_scale);
}
-
-void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0,
- uint32_t operand1) {
+void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, int operand_scale,
+ uint32_t operand0, uint32_t operand1) {
uint32_t operands[] = {operand0, operand1};
- Output(bytecode, operands);
+ Output(bytecode, operands, operand_scale);
}
-
-void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t operand0) {
+void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode, int operand_scale,
+ uint32_t operand0) {
uint32_t operands[] = {operand0};
- Output(bytecode, operands);
-}
-
-
-void BytecodeArrayBuilder::Output(Bytecode bytecode) {
- // Don't output dead code.
- if (exit_seen_in_block_) return;
-
- DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 0);
- last_bytecode_start_ = bytecodes()->size();
- bytecodes()->push_back(Bytecodes::ToByte(bytecode));
+ Output(bytecode, operands, operand_scale);
}
BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op,
Register reg) {
- Output(BytecodeForBinaryOperation(op), reg.ToRawOperand());
+ int operand_scale = OperandScale(SizeForRegisterOperand(reg));
+ OutputScaled(BytecodeForBinaryOperation(op), operand_scale,
+ reg.ToRawOperand());
return *this;
}
@@ -250,7 +278,9 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::TypeOf() {
BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation(Token::Value op,
Register reg) {
- Output(BytecodeForCompareOperation(op), reg.ToRawOperand());
+ int operand_scale = OperandScale(SizeForRegisterOperand(reg));
+ OutputScaled(BytecodeForCompareOperation(op), operand_scale,
+ reg.ToRawOperand());
return *this;
}
@@ -260,10 +290,11 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(
int32_t raw_smi = smi->value();
if (raw_smi == 0) {
Output(Bytecode::kLdaZero);
- } else if (raw_smi >= -128 && raw_smi <= 127) {
- Output(Bytecode::kLdaSmi8, static_cast<uint8_t>(raw_smi));
} else {
- LoadLiteral(Handle<Object>(smi, isolate_));
+ OperandSize operand_size = SizeForSignedOperand(raw_smi);
+ int operand_scale = OperandScale(operand_size);
+ OutputScaled(Bytecode::kLdaSmi, operand_scale,
+ SignedOperand(raw_smi, operand_size));
}
return *this;
}
@@ -271,13 +302,8 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(
BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(Handle<Object> object) {
size_t entry = GetConstantPoolEntry(object);
- if (FitsInIdx8Operand(entry)) {
- Output(Bytecode::kLdaConstant, static_cast<uint8_t>(entry));
- } else if (FitsInIdx16Operand(entry)) {
- Output(Bytecode::kLdaConstantWide, static_cast<uint16_t>(entry));
- } else {
- UNIMPLEMENTED();
- }
+ int operand_scale = OperandScale(SizeForUnsignedOperand(entry));
+ OutputScaled(Bytecode::kLdaConstant, operand_scale, UnsignedOperand(entry));
return *this;
}
@@ -324,7 +350,8 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadBooleanConstant(bool value) {
BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister(
Register reg) {
if (!IsRegisterInAccumulator(reg)) {
- Output(Bytecode::kLdar, reg.ToRawOperand());
+ int operand_scale = OperandScale(SizeForRegisterOperand(reg));
+ OutputScaled(Bytecode::kLdar, operand_scale, reg.ToRawOperand());
}
return *this;
}
@@ -333,7 +360,8 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister(
BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister(
Register reg) {
if (!IsRegisterInAccumulator(reg)) {
- Output(Bytecode::kStar, reg.ToRawOperand());
+ int operand_scale = OperandScale(SizeForRegisterOperand(reg));
+ OutputScaled(Bytecode::kStar, operand_scale, reg.ToRawOperand());
}
return *this;
}
@@ -342,164 +370,94 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister(
BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from,
Register to) {
DCHECK(from != to);
- if (FitsInReg8Operand(from) && FitsInReg8Operand(to)) {
- Output(Bytecode::kMov, from.ToRawOperand(), to.ToRawOperand());
- } else if (FitsInReg16Operand(from) && FitsInReg16Operand(to)) {
- Output(Bytecode::kMovWide, from.ToRawOperand(), to.ToRawOperand());
- } else {
- UNIMPLEMENTED();
- }
+ int operand_scale =
+ OperandScale(SizeForRegisterOperand(from), SizeForRegisterOperand(to));
+ OutputScaled(Bytecode::kMov, operand_scale, from.ToRawOperand(),
+ to.ToRawOperand());
return *this;
}
-void BytecodeArrayBuilder::MoveRegisterUntranslated(Register from,
- Register to) {
- // Move bytecodes modify the stack. Checking validity is an
- // essential mitigation against corrupting the stack.
- if (FitsInReg8OperandUntranslated(from)) {
- CHECK(RegisterIsValid(from, OperandType::kReg8) &&
- RegisterIsValid(to, OperandType::kReg16));
- } else if (FitsInReg8OperandUntranslated(to)) {
- CHECK(RegisterIsValid(from, OperandType::kReg16) &&
- RegisterIsValid(to, OperandType::kReg8));
- } else {
- UNIMPLEMENTED();
- }
- Output(Bytecode::kMovWide, from.ToRawOperand(), to.ToRawOperand());
-}
-
BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal(
const Handle<String> name, int feedback_slot, TypeofMode typeof_mode) {
// TODO(rmcilroy): Potentially store typeof information in an
// operand rather than having extra bytecodes.
Bytecode bytecode = BytecodeForLoadGlobal(typeof_mode);
size_t name_index = GetConstantPoolEntry(name);
- if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) {
- Output(bytecode, static_cast<uint8_t>(name_index),
- static_cast<uint8_t>(feedback_slot));
- } else if (FitsInIdx16Operand(name_index) &&
- FitsInIdx16Operand(feedback_slot)) {
- Output(BytecodeForWideOperands(bytecode), static_cast<uint16_t>(name_index),
- static_cast<uint16_t>(feedback_slot));
- } else {
- UNIMPLEMENTED();
- }
+ int operand_scale = OperandScale(SizeForUnsignedOperand(name_index),
+ SizeForUnsignedOperand(feedback_slot));
+ OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index),
+ UnsignedOperand(feedback_slot));
return *this;
}
-
BytecodeArrayBuilder& BytecodeArrayBuilder::StoreGlobal(
const Handle<String> name, int feedback_slot, LanguageMode language_mode) {
Bytecode bytecode = BytecodeForStoreGlobal(language_mode);
size_t name_index = GetConstantPoolEntry(name);
- if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) {
- Output(bytecode, static_cast<uint8_t>(name_index),
- static_cast<uint8_t>(feedback_slot));
- } else if (FitsInIdx16Operand(name_index) &&
- FitsInIdx16Operand(feedback_slot)) {
- Output(BytecodeForWideOperands(bytecode), static_cast<uint16_t>(name_index),
- static_cast<uint16_t>(feedback_slot));
- } else {
- UNIMPLEMENTED();
- }
+ int operand_scale = OperandScale(SizeForUnsignedOperand(name_index),
+ SizeForUnsignedOperand(feedback_slot));
+ OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index),
+ UnsignedOperand(feedback_slot));
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context,
int slot_index) {
- DCHECK(slot_index >= 0);
- if (FitsInIdx8Operand(slot_index)) {
- Output(Bytecode::kLdaContextSlot, context.ToRawOperand(),
- static_cast<uint8_t>(slot_index));
- } else if (FitsInIdx16Operand(slot_index)) {
- Output(Bytecode::kLdaContextSlotWide, context.ToRawOperand(),
- static_cast<uint16_t>(slot_index));
- } else {
- UNIMPLEMENTED();
- }
+ int operand_scale = OperandScale(SizeForRegisterOperand(context),
+ SizeForUnsignedOperand(slot_index));
+ OutputScaled(Bytecode::kLdaContextSlot, operand_scale, context.ToRawOperand(),
+ UnsignedOperand(slot_index));
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context,
int slot_index) {
- DCHECK(slot_index >= 0);
- if (FitsInIdx8Operand(slot_index)) {
- Output(Bytecode::kStaContextSlot, context.ToRawOperand(),
- static_cast<uint8_t>(slot_index));
- } else if (FitsInIdx16Operand(slot_index)) {
- Output(Bytecode::kStaContextSlotWide, context.ToRawOperand(),
- static_cast<uint16_t>(slot_index));
- } else {
- UNIMPLEMENTED();
- }
+ int operand_scale = OperandScale(SizeForRegisterOperand(context),
+ SizeForUnsignedOperand(slot_index));
+ OutputScaled(Bytecode::kStaContextSlot, operand_scale, context.ToRawOperand(),
+ UnsignedOperand(slot_index));
return *this;
}
-
BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupSlot(
const Handle<String> name, TypeofMode typeof_mode) {
Bytecode bytecode = (typeof_mode == INSIDE_TYPEOF)
? Bytecode::kLdaLookupSlotInsideTypeof
: Bytecode::kLdaLookupSlot;
size_t name_index = GetConstantPoolEntry(name);
- if (FitsInIdx8Operand(name_index)) {
- Output(bytecode, static_cast<uint8_t>(name_index));
- } else if (FitsInIdx16Operand(name_index)) {
- Output(BytecodeForWideOperands(bytecode),
- static_cast<uint16_t>(name_index));
- } else {
- UNIMPLEMENTED();
- }
+ int operand_scale = OperandScale(SizeForUnsignedOperand(name_index));
+ OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index));
return *this;
}
-
BytecodeArrayBuilder& BytecodeArrayBuilder::StoreLookupSlot(
const Handle<String> name, LanguageMode language_mode) {
Bytecode bytecode = BytecodeForStoreLookupSlot(language_mode);
size_t name_index = GetConstantPoolEntry(name);
- if (FitsInIdx8Operand(name_index)) {
- Output(bytecode, static_cast<uint8_t>(name_index));
- } else if (FitsInIdx16Operand(name_index)) {
- Output(BytecodeForWideOperands(bytecode),
- static_cast<uint16_t>(name_index));
- } else {
- UNIMPLEMENTED();
- }
+ int operand_scale = OperandScale(SizeForUnsignedOperand(name_index));
+ OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index));
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty(
Register object, const Handle<Name> name, int feedback_slot) {
size_t name_index = GetConstantPoolEntry(name);
- if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) {
- Output(Bytecode::kLoadIC, object.ToRawOperand(),
- static_cast<uint8_t>(name_index),
- static_cast<uint8_t>(feedback_slot));
- } else if (FitsInIdx16Operand(name_index) &&
- FitsInIdx16Operand(feedback_slot)) {
- Output(Bytecode::kLoadICWide, object.ToRawOperand(),
- static_cast<uint16_t>(name_index),
- static_cast<uint16_t>(feedback_slot));
- } else {
- UNIMPLEMENTED();
- }
+ int operand_scale = OperandScale(SizeForRegisterOperand(object),
+ SizeForUnsignedOperand(name_index),
+ SizeForUnsignedOperand(feedback_slot));
+ OutputScaled(Bytecode::kLoadIC, operand_scale, object.ToRawOperand(),
+ UnsignedOperand(name_index), UnsignedOperand(feedback_slot));
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty(
Register object, int feedback_slot) {
- if (FitsInIdx8Operand(feedback_slot)) {
- Output(Bytecode::kKeyedLoadIC, object.ToRawOperand(),
- static_cast<uint8_t>(feedback_slot));
- } else if (FitsInIdx16Operand(feedback_slot)) {
- Output(Bytecode::kKeyedLoadICWide, object.ToRawOperand(),
- static_cast<uint16_t>(feedback_slot));
- } else {
- UNIMPLEMENTED();
- }
+ int operand_scale = OperandScale(SizeForRegisterOperand(object),
+ SizeForUnsignedOperand(feedback_slot));
+ OutputScaled(Bytecode::kKeyedLoadIC, operand_scale, object.ToRawOperand(),
+ UnsignedOperand(feedback_slot));
return *this;
}
@@ -508,17 +466,11 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty(
LanguageMode language_mode) {
Bytecode bytecode = BytecodeForStoreIC(language_mode);
size_t name_index = GetConstantPoolEntry(name);
- if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) {
- Output(bytecode, object.ToRawOperand(), static_cast<uint8_t>(name_index),
- static_cast<uint8_t>(feedback_slot));
- } else if (FitsInIdx16Operand(name_index) &&
- FitsInIdx16Operand(feedback_slot)) {
- Output(BytecodeForWideOperands(bytecode), object.ToRawOperand(),
- static_cast<uint16_t>(name_index),
- static_cast<uint16_t>(feedback_slot));
- } else {
- UNIMPLEMENTED();
- }
+ int operand_scale = OperandScale(SizeForRegisterOperand(object),
+ SizeForUnsignedOperand(name_index),
+ SizeForUnsignedOperand(feedback_slot));
+ OutputScaled(bytecode, operand_scale, object.ToRawOperand(),
+ UnsignedOperand(name_index), UnsignedOperand(feedback_slot));
return *this;
}
@@ -527,15 +479,11 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty(
Register object, Register key, int feedback_slot,
LanguageMode language_mode) {
Bytecode bytecode = BytecodeForKeyedStoreIC(language_mode);
- if (FitsInIdx8Operand(feedback_slot)) {
- Output(bytecode, object.ToRawOperand(), key.ToRawOperand(),
- static_cast<uint8_t>(feedback_slot));
- } else if (FitsInIdx16Operand(feedback_slot)) {
- Output(BytecodeForWideOperands(bytecode), object.ToRawOperand(),
- key.ToRawOperand(), static_cast<uint16_t>(feedback_slot));
- } else {
- UNIMPLEMENTED();
- }
+ int operand_scale =
+ OperandScale(SizeForRegisterOperand(object), SizeForRegisterOperand(key),
+ SizeForUnsignedOperand(feedback_slot));
+ OutputScaled(bytecode, operand_scale, object.ToRawOperand(),
+ key.ToRawOperand(), UnsignedOperand(feedback_slot));
return *this;
}
@@ -543,16 +491,9 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty(
BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure(
Handle<SharedFunctionInfo> shared_info, PretenureFlag tenured) {
size_t entry = GetConstantPoolEntry(shared_info);
- DCHECK(FitsInImm8Operand(tenured));
- if (FitsInIdx8Operand(entry)) {
- Output(Bytecode::kCreateClosure, static_cast<uint8_t>(entry),
- static_cast<uint8_t>(tenured));
- } else if (FitsInIdx16Operand(entry)) {
- Output(Bytecode::kCreateClosureWide, static_cast<uint16_t>(entry),
- static_cast<uint8_t>(tenured));
- } else {
- UNIMPLEMENTED();
- }
+ int operand_scale = OperandScale(SizeForUnsignedOperand(entry));
+ OutputScaled(Bytecode::kCreateClosure, operand_scale, UnsignedOperand(entry),
+ UnsignedOperand(static_cast<size_t>(tenured)));
return *this;
}
@@ -570,73 +511,53 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArguments(
BytecodeArrayBuilder& BytecodeArrayBuilder::CreateRegExpLiteral(
Handle<String> pattern, int literal_index, int flags) {
- DCHECK(FitsInImm8Operand(flags)); // Flags should fit in 8 bits.
size_t pattern_entry = GetConstantPoolEntry(pattern);
- if (FitsInIdx8Operand(literal_index) && FitsInIdx8Operand(pattern_entry)) {
- Output(Bytecode::kCreateRegExpLiteral, static_cast<uint8_t>(pattern_entry),
- static_cast<uint8_t>(literal_index), static_cast<uint8_t>(flags));
- } else if (FitsInIdx16Operand(literal_index) &&
- FitsInIdx16Operand(pattern_entry)) {
- Output(Bytecode::kCreateRegExpLiteralWide,
- static_cast<uint16_t>(pattern_entry),
- static_cast<uint16_t>(literal_index), static_cast<uint8_t>(flags));
- } else {
- UNIMPLEMENTED();
- }
+ int operand_scale = OperandScale(SizeForUnsignedOperand(pattern_entry),
+ SizeForUnsignedOperand(literal_index),
+ SizeForUnsignedOperand(flags));
+ OutputScaled(Bytecode::kCreateRegExpLiteral, operand_scale,
+ UnsignedOperand(pattern_entry), UnsignedOperand(literal_index),
+ UnsignedOperand(flags));
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArrayLiteral(
Handle<FixedArray> constant_elements, int literal_index, int flags) {
- DCHECK(FitsInImm8Operand(flags)); // Flags should fit in 8 bits.
size_t constant_elements_entry = GetConstantPoolEntry(constant_elements);
- if (FitsInIdx8Operand(literal_index) &&
- FitsInIdx8Operand(constant_elements_entry)) {
- Output(Bytecode::kCreateArrayLiteral,
- static_cast<uint8_t>(constant_elements_entry),
- static_cast<uint8_t>(literal_index), static_cast<uint8_t>(flags));
- } else if (FitsInIdx16Operand(literal_index) &&
- FitsInIdx16Operand(constant_elements_entry)) {
- Output(Bytecode::kCreateArrayLiteralWide,
- static_cast<uint16_t>(constant_elements_entry),
- static_cast<uint16_t>(literal_index), static_cast<uint8_t>(flags));
- } else {
- UNIMPLEMENTED();
- }
+ int operand_scale = OperandScale(
+ SizeForUnsignedOperand(constant_elements_entry),
+ SizeForUnsignedOperand(literal_index), SizeForUnsignedOperand(flags));
+ OutputScaled(Bytecode::kCreateArrayLiteral, operand_scale,
+ UnsignedOperand(constant_elements_entry),
+ UnsignedOperand(literal_index), UnsignedOperand(flags));
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::CreateObjectLiteral(
Handle<FixedArray> constant_properties, int literal_index, int flags) {
- DCHECK(FitsInImm8Operand(flags)); // Flags should fit in 8 bits.
size_t constant_properties_entry = GetConstantPoolEntry(constant_properties);
- if (FitsInIdx8Operand(literal_index) &&
- FitsInIdx8Operand(constant_properties_entry)) {
- Output(Bytecode::kCreateObjectLiteral,
- static_cast<uint8_t>(constant_properties_entry),
- static_cast<uint8_t>(literal_index), static_cast<uint8_t>(flags));
- } else if (FitsInIdx16Operand(literal_index) &&
- FitsInIdx16Operand(constant_properties_entry)) {
- Output(Bytecode::kCreateObjectLiteralWide,
- static_cast<uint16_t>(constant_properties_entry),
- static_cast<uint16_t>(literal_index), static_cast<uint8_t>(flags));
- } else {
- UNIMPLEMENTED();
- }
+ int operand_scale = OperandScale(
+ SizeForUnsignedOperand(constant_properties_entry),
+ SizeForUnsignedOperand(literal_index), SizeForUnsignedOperand(flags));
+ OutputScaled(Bytecode::kCreateObjectLiteral, operand_scale,
+ UnsignedOperand(constant_properties_entry),
+ UnsignedOperand(literal_index), UnsignedOperand(flags));
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::PushContext(Register context) {
- Output(Bytecode::kPushContext, context.ToRawOperand());
+ int operand_scale = OperandScale(SizeForRegisterOperand(context));
+ OutputScaled(Bytecode::kPushContext, operand_scale, context.ToRawOperand());
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) {
- Output(Bytecode::kPopContext, context.ToRawOperand());
+ int operand_scale = OperandScale(SizeForRegisterOperand(context));
+ OutputScaled(Bytecode::kPopContext, operand_scale, context.ToRawOperand());
return *this;
}
@@ -681,7 +602,6 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToName() {
case Bytecode::kToName:
case Bytecode::kTypeOf:
return *this;
- case Bytecode::kLdaConstantWide:
case Bytecode::kLdaConstant: {
Handle<Object> object = previous_bytecode.GetConstantForIndexOperand(0);
if (object->IsName()) return *this;
@@ -754,34 +674,6 @@ Bytecode BytecodeArrayBuilder::GetJumpWithConstantOperand(
}
}
-
-// static
-Bytecode BytecodeArrayBuilder::GetJumpWithConstantWideOperand(
- Bytecode jump_bytecode) {
- switch (jump_bytecode) {
- case Bytecode::kJump:
- return Bytecode::kJumpConstantWide;
- case Bytecode::kJumpIfTrue:
- return Bytecode::kJumpIfTrueConstantWide;
- case Bytecode::kJumpIfFalse:
- return Bytecode::kJumpIfFalseConstantWide;
- case Bytecode::kJumpIfToBooleanTrue:
- return Bytecode::kJumpIfToBooleanTrueConstantWide;
- case Bytecode::kJumpIfToBooleanFalse:
- return Bytecode::kJumpIfToBooleanFalseConstantWide;
- case Bytecode::kJumpIfNotHole:
- return Bytecode::kJumpIfNotHoleConstantWide;
- case Bytecode::kJumpIfNull:
- return Bytecode::kJumpIfNullConstantWide;
- case Bytecode::kJumpIfUndefined:
- return Bytecode::kJumpIfUndefinedConstantWide;
- default:
- UNREACHABLE();
- return static_cast<Bytecode>(-1);
- }
-}
-
-
// static
Bytecode BytecodeArrayBuilder::GetJumpWithToBoolean(Bytecode jump_bytecode) {
switch (jump_bytecode) {
@@ -807,54 +699,85 @@ void BytecodeArrayBuilder::PatchIndirectJumpWith8BitOperand(
DCHECK(Bytecodes::IsJumpImmediate(jump_bytecode));
ZoneVector<uint8_t>::iterator operand_location = jump_location + 1;
DCHECK_EQ(*operand_location, 0);
- if (FitsInImm8Operand(delta)) {
- // The jump fits within the range of an Imm8 operand, so cancel
+ if (SizeForSignedOperand(delta) == OperandSize::kByte) {
+ // The jump fits within the range of an Imm operand, so cancel
// the reservation and jump directly.
constant_array_builder()->DiscardReservedEntry(OperandSize::kByte);
*operand_location = static_cast<uint8_t>(delta);
} else {
- // The jump does not fit within the range of an Imm8 operand, so
+ // The jump does not fit within the range of an Imm operand, so
// commit reservation putting the offset into the constant pool,
// and update the jump instruction and operand.
size_t entry = constant_array_builder()->CommitReservedEntry(
OperandSize::kByte, handle(Smi::FromInt(delta), isolate()));
- DCHECK(FitsInIdx8Operand(entry));
+ DCHECK(SizeForUnsignedOperand(entry) == OperandSize::kByte);
jump_bytecode = GetJumpWithConstantOperand(jump_bytecode);
*jump_location = Bytecodes::ToByte(jump_bytecode);
*operand_location = static_cast<uint8_t>(entry);
}
}
-
void BytecodeArrayBuilder::PatchIndirectJumpWith16BitOperand(
const ZoneVector<uint8_t>::iterator& jump_location, int delta) {
- DCHECK(Bytecodes::IsJumpConstantWide(Bytecodes::FromByte(*jump_location)));
+ Bytecode jump_bytecode = Bytecodes::FromByte(*jump_location);
+ DCHECK(Bytecodes::IsJumpImmediate(jump_bytecode));
ZoneVector<uint8_t>::iterator operand_location = jump_location + 1;
- size_t entry = constant_array_builder()->CommitReservedEntry(
- OperandSize::kShort, handle(Smi::FromInt(delta), isolate()));
- DCHECK(FitsInIdx16Operand(entry));
uint8_t operand_bytes[2];
- WriteUnalignedUInt16(operand_bytes, static_cast<uint16_t>(entry));
+ if (SizeForSignedOperand(delta) <= OperandSize::kShort) {
+ constant_array_builder()->DiscardReservedEntry(OperandSize::kShort);
+ WriteUnalignedUInt16(operand_bytes, static_cast<uint16_t>(delta));
+ } else {
+ jump_bytecode = GetJumpWithConstantOperand(jump_bytecode);
+ *jump_location = Bytecodes::ToByte(jump_bytecode);
+ size_t entry = constant_array_builder()->CommitReservedEntry(
+ OperandSize::kShort, handle(Smi::FromInt(delta), isolate()));
+ WriteUnalignedUInt16(operand_bytes, static_cast<uint16_t>(entry));
+ }
DCHECK(*operand_location == 0 && *(operand_location + 1) == 0);
*operand_location++ = operand_bytes[0];
*operand_location = operand_bytes[1];
}
+void BytecodeArrayBuilder::PatchIndirectJumpWith32BitOperand(
+ const ZoneVector<uint8_t>::iterator& jump_location, int delta) {
+ DCHECK(Bytecodes::IsJumpImmediate(Bytecodes::FromByte(*jump_location)));
+ constant_array_builder()->DiscardReservedEntry(OperandSize::kQuad);
+ ZoneVector<uint8_t>::iterator operand_location = jump_location + 1;
+ uint8_t operand_bytes[4];
+ WriteUnalignedUInt32(operand_bytes, static_cast<uint32_t>(delta));
+ DCHECK(*operand_location == 0 && *(operand_location + 1) == 0 &&
+ *(operand_location + 2) == 0 && *(operand_location + 3) == 0);
+ *operand_location++ = operand_bytes[0];
+ *operand_location++ = operand_bytes[1];
+ *operand_location++ = operand_bytes[2];
+ *operand_location = operand_bytes[3];
+}
void BytecodeArrayBuilder::PatchJump(
const ZoneVector<uint8_t>::iterator& jump_target,
const ZoneVector<uint8_t>::iterator& jump_location) {
- Bytecode jump_bytecode = Bytecodes::FromByte(*jump_location);
int delta = static_cast<int>(jump_target - jump_location);
+ Bytecode jump_bytecode = Bytecodes::FromByte(*jump_location);
+ int operand_scale = Bytecodes::GetPrefixBytecodeScale(jump_bytecode);
+ int prefix_offset = 0;
+ if (operand_scale > 1) {
+ delta -= 1;
+ prefix_offset = 1;
+ jump_bytecode = Bytecodes::FromByte(*(jump_location + prefix_offset));
+ }
+
DCHECK(Bytecodes::IsJump(jump_bytecode));
- switch (Bytecodes::GetOperandSize(jump_bytecode, 0)) {
- case OperandSize::kByte:
+ switch (operand_scale) {
+ case 1:
PatchIndirectJumpWith8BitOperand(jump_location, delta);
break;
- case OperandSize::kShort:
- PatchIndirectJumpWith16BitOperand(jump_location, delta);
+ case 2:
+ PatchIndirectJumpWith16BitOperand(jump_location + prefix_offset, delta);
break;
- case OperandSize::kNone:
+ case 4:
+ PatchIndirectJumpWith32BitOperand(jump_location + prefix_offset, delta);
+ break;
+ default:
UNREACHABLE();
}
unbound_jumps_--;
@@ -878,22 +801,14 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode,
CHECK_LE(bytecodes()->size(), static_cast<size_t>(kMaxInt));
size_t abs_delta = bytecodes()->size() - label->offset();
int delta = -static_cast<int>(abs_delta);
-
- if (FitsInImm8Operand(delta)) {
- Output(jump_bytecode, static_cast<uint8_t>(delta));
- } else {
- size_t entry =
- GetConstantPoolEntry(handle(Smi::FromInt(delta), isolate()));
- if (FitsInIdx8Operand(entry)) {
- Output(GetJumpWithConstantOperand(jump_bytecode),
- static_cast<uint8_t>(entry));
- } else if (FitsInIdx16Operand(entry)) {
- Output(GetJumpWithConstantWideOperand(jump_bytecode),
- static_cast<uint16_t>(entry));
- } else {
- UNREACHABLE();
- }
+ OperandSize operand_size = SizeForSignedOperand(delta);
+ if (operand_size > OperandSize::kByte) {
+ // Adjust for scaling byte prefix for wide jump offset.
+ DCHECK_LE(delta, 0);
+ delta -= 1;
}
+ OutputScaled(jump_bytecode, static_cast<int>(operand_size),
+ SignedOperand(delta, operand_size));
} else {
// The label has not yet been bound so this is a forward reference
// that will be patched when the label is bound. We create a
@@ -905,16 +820,7 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode,
unbound_jumps_++;
OperandSize reserved_operand_size =
constant_array_builder()->CreateReservedEntry();
- switch (reserved_operand_size) {
- case OperandSize::kByte:
- Output(jump_bytecode, 0);
- break;
- case OperandSize::kShort:
- Output(GetJumpWithConstantWideOperand(jump_bytecode), 0);
- break;
- case OperandSize::kNone:
- UNREACHABLE();
- }
+ OutputScaled(jump_bytecode, static_cast<int>(reserved_operand_size), 0);
}
LeaveBasicBlock();
return *this;
@@ -984,48 +890,38 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::Debugger() {
BytecodeArrayBuilder& BytecodeArrayBuilder::ForInPrepare(
Register cache_info_triple) {
- if (FitsInReg8Operand(cache_info_triple)) {
- Output(Bytecode::kForInPrepare, cache_info_triple.ToRawOperand());
- } else if (FitsInReg16Operand(cache_info_triple)) {
- Output(Bytecode::kForInPrepareWide, cache_info_triple.ToRawOperand());
- } else {
- UNIMPLEMENTED();
- }
+ int operand_scale = OperandScale(SizeForRegisterOperand(cache_info_triple));
+ OutputScaled(Bytecode::kForInPrepare, operand_scale,
+ cache_info_triple.ToRawOperand());
return *this;
}
-
BytecodeArrayBuilder& BytecodeArrayBuilder::ForInDone(Register index,
Register cache_length) {
- Output(Bytecode::kForInDone, index.ToRawOperand(),
- cache_length.ToRawOperand());
+ int operand_scale = OperandScale(SizeForRegisterOperand(index),
+ SizeForRegisterOperand(cache_length));
+ OutputScaled(Bytecode::kForInDone, operand_scale, index.ToRawOperand(),
+ cache_length.ToRawOperand());
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::ForInNext(
Register receiver, Register index, Register cache_type_array_pair,
int feedback_slot) {
- if (FitsInReg8Operand(receiver) && FitsInReg8Operand(index) &&
- FitsInReg8Operand(cache_type_array_pair) &&
- FitsInIdx8Operand(feedback_slot)) {
- Output(Bytecode::kForInNext, receiver.ToRawOperand(), index.ToRawOperand(),
- cache_type_array_pair.ToRawOperand(),
- static_cast<uint8_t>(feedback_slot));
- } else if (FitsInReg16Operand(receiver) && FitsInReg16Operand(index) &&
- FitsInReg16Operand(cache_type_array_pair) &&
- FitsInIdx16Operand(feedback_slot)) {
- Output(Bytecode::kForInNextWide, receiver.ToRawOperand(),
- index.ToRawOperand(), cache_type_array_pair.ToRawOperand(),
- static_cast<uint16_t>(feedback_slot));
- } else {
- UNIMPLEMENTED();
- }
+ int operand_scale = OperandScale(
+ SizeForRegisterOperand(receiver), SizeForRegisterOperand(index),
+ SizeForRegisterOperand(cache_type_array_pair),
+ SizeForUnsignedOperand(feedback_slot));
+ OutputScaled(Bytecode::kForInNext, operand_scale, receiver.ToRawOperand(),
+ index.ToRawOperand(), cache_type_array_pair.ToRawOperand(),
+ UnsignedOperand(feedback_slot));
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::ForInStep(Register index) {
- Output(Bytecode::kForInStep, index.ToRawOperand());
+ int operand_scale = OperandScale(SizeForRegisterOperand(index));
+ OutputScaled(Bytecode::kForInStep, operand_scale, index.ToRawOperand());
return *this;
}
@@ -1071,23 +967,14 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable,
int feedback_slot,
TailCallMode tail_call_mode) {
Bytecode bytecode = BytecodeForCall(tail_call_mode);
- if (FitsInReg8Operand(callable) && FitsInReg8Operand(receiver_args) &&
- FitsInIdx8Operand(receiver_args_count) &&
- FitsInIdx8Operand(feedback_slot)) {
- Output(bytecode, callable.ToRawOperand(), receiver_args.ToRawOperand(),
- static_cast<uint8_t>(receiver_args_count),
- static_cast<uint8_t>(feedback_slot));
- } else if (FitsInReg16Operand(callable) &&
- FitsInReg16Operand(receiver_args) &&
- FitsInIdx16Operand(receiver_args_count) &&
- FitsInIdx16Operand(feedback_slot)) {
- bytecode = BytecodeForWideOperands(bytecode);
- Output(bytecode, callable.ToRawOperand(), receiver_args.ToRawOperand(),
- static_cast<uint16_t>(receiver_args_count),
- static_cast<uint16_t>(feedback_slot));
- } else {
- UNIMPLEMENTED();
- }
+ int operand_scale = OperandScale(SizeForRegisterOperand(callable),
+ SizeForRegisterOperand(receiver_args),
+ SizeForUnsignedOperand(receiver_args_count),
+ SizeForUnsignedOperand(feedback_slot));
+ OutputScaled(bytecode, operand_scale, callable.ToRawOperand(),
+ receiver_args.ToRawOperand(),
+ UnsignedOperand(receiver_args_count),
+ UnsignedOperand(feedback_slot));
return *this;
}
@@ -1098,17 +985,11 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor,
DCHECK_EQ(0u, arg_count);
first_arg = Register(0);
}
- if (FitsInReg8Operand(constructor) && FitsInReg8Operand(first_arg) &&
- FitsInIdx8Operand(arg_count)) {
- Output(Bytecode::kNew, constructor.ToRawOperand(), first_arg.ToRawOperand(),
- static_cast<uint8_t>(arg_count));
- } else if (FitsInReg16Operand(constructor) && FitsInReg16Operand(first_arg) &&
- FitsInIdx16Operand(arg_count)) {
- Output(Bytecode::kNewWide, constructor.ToRawOperand(),
- first_arg.ToRawOperand(), static_cast<uint16_t>(arg_count));
- } else {
- UNIMPLEMENTED();
- }
+ int operand_scale = OperandScale(SizeForRegisterOperand(constructor),
+ SizeForRegisterOperand(first_arg),
+ SizeForUnsignedOperand(arg_count));
+ OutputScaled(Bytecode::kNew, operand_scale, constructor.ToRawOperand(),
+ first_arg.ToRawOperand(), UnsignedOperand(arg_count));
return *this;
}
@@ -1116,20 +997,16 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor,
BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime(
Runtime::FunctionId function_id, Register first_arg, size_t arg_count) {
DCHECK_EQ(1, Runtime::FunctionForId(function_id)->result_size);
- DCHECK(FitsInIdx16Operand(function_id));
+ DCHECK(SizeForUnsignedOperand(function_id) <= OperandSize::kShort);
if (!first_arg.is_valid()) {
DCHECK_EQ(0u, arg_count);
first_arg = Register(0);
}
- if (FitsInReg8Operand(first_arg) && FitsInIdx8Operand(arg_count)) {
- Output(Bytecode::kCallRuntime, static_cast<uint16_t>(function_id),
- first_arg.ToRawOperand(), static_cast<uint8_t>(arg_count));
- } else if (FitsInReg16Operand(first_arg) && FitsInIdx16Operand(arg_count)) {
- Output(Bytecode::kCallRuntimeWide, static_cast<uint16_t>(function_id),
- first_arg.ToRawOperand(), static_cast<uint16_t>(arg_count));
- } else {
- UNIMPLEMENTED();
- }
+ int operand_scale = OperandScale(SizeForRegisterOperand(first_arg),
+ SizeForUnsignedOperand(arg_count));
+ OutputScaled(Bytecode::kCallRuntime, operand_scale,
+ static_cast<uint16_t>(function_id), first_arg.ToRawOperand(),
+ UnsignedOperand(arg_count));
return *this;
}
@@ -1138,50 +1015,37 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntimeForPair(
Runtime::FunctionId function_id, Register first_arg, size_t arg_count,
Register first_return) {
DCHECK_EQ(2, Runtime::FunctionForId(function_id)->result_size);
- DCHECK(FitsInIdx16Operand(function_id));
+ DCHECK(SizeForUnsignedOperand(function_id) <= OperandSize::kShort);
if (!first_arg.is_valid()) {
DCHECK_EQ(0u, arg_count);
first_arg = Register(0);
}
- if (FitsInReg8Operand(first_arg) && FitsInIdx8Operand(arg_count) &&
- FitsInReg8Operand(first_return)) {
- Output(Bytecode::kCallRuntimeForPair, static_cast<uint16_t>(function_id),
- first_arg.ToRawOperand(), static_cast<uint8_t>(arg_count),
- first_return.ToRawOperand());
- } else if (FitsInReg16Operand(first_arg) && FitsInIdx16Operand(arg_count) &&
- FitsInReg16Operand(first_return)) {
- Output(Bytecode::kCallRuntimeForPairWide,
- static_cast<uint16_t>(function_id), first_arg.ToRawOperand(),
- static_cast<uint16_t>(arg_count), first_return.ToRawOperand());
- } else {
- UNIMPLEMENTED();
- }
+ int operand_scale = OperandScale(SizeForRegisterOperand(first_arg),
+ SizeForUnsignedOperand(arg_count),
+ SizeForRegisterOperand(first_return));
+ OutputScaled(Bytecode::kCallRuntimeForPair, operand_scale,
+ static_cast<uint16_t>(function_id), first_arg.ToRawOperand(),
+ UnsignedOperand(arg_count), first_return.ToRawOperand());
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime(
int context_index, Register receiver_args, size_t receiver_args_count) {
- DCHECK(FitsInIdx16Operand(context_index));
- if (FitsInReg8Operand(receiver_args) &&
- FitsInIdx8Operand(receiver_args_count)) {
- Output(Bytecode::kCallJSRuntime, static_cast<uint16_t>(context_index),
- receiver_args.ToRawOperand(),
- static_cast<uint8_t>(receiver_args_count));
- } else if (FitsInReg16Operand(receiver_args) &&
- FitsInIdx16Operand(receiver_args_count)) {
- Output(Bytecode::kCallJSRuntimeWide, static_cast<uint16_t>(context_index),
- receiver_args.ToRawOperand(),
- static_cast<uint16_t>(receiver_args_count));
- } else {
- UNIMPLEMENTED();
- }
+ int operand_scale = OperandScale(SizeForUnsignedOperand(context_index),
+ SizeForRegisterOperand(receiver_args),
+ SizeForUnsignedOperand(receiver_args_count));
+ OutputScaled(Bytecode::kCallJSRuntime, operand_scale,
+ UnsignedOperand(context_index), receiver_args.ToRawOperand(),
+ UnsignedOperand(receiver_args_count));
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object,
LanguageMode language_mode) {
- Output(BytecodeForDelete(language_mode), object.ToRawOperand());
+ int operand_scale = OperandScale(SizeForRegisterOperand(object));
+ OutputScaled(BytecodeForDelete(language_mode), operand_scale,
+ object.ToRawOperand());
return *this;
}
@@ -1223,106 +1087,70 @@ bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const {
}
bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, int operand_index,
+ int operand_scale,
uint32_t operand_value) const {
+ OperandSize operand_size =
+ Bytecodes::GetOperandSize(bytecode, operand_index, operand_scale);
OperandType operand_type = Bytecodes::GetOperandType(bytecode, operand_index);
switch (operand_type) {
case OperandType::kNone:
return false;
- case OperandType::kRegCount16: {
- // Expect kRegCount16 is part of a range previous operand is a
- // valid operand to start a range.
- if (operand_index > 0) {
- OperandType previous_operand_type =
- Bytecodes::GetOperandType(bytecode, operand_index - 1);
- return ((previous_operand_type == OperandType::kMaybeReg16 ||
- previous_operand_type == OperandType::kReg16) &&
- static_cast<uint16_t>(operand_value) == operand_value);
- } else {
- return false;
- }
- }
- case OperandType::kRegCount8: {
- // Expect kRegCount8 is part of a range previous operand is a
- // valid operand to start a range.
+ case OperandType::kRegCount: {
if (operand_index > 0) {
OperandType previous_operand_type =
Bytecodes::GetOperandType(bytecode, operand_index - 1);
- return ((previous_operand_type == OperandType::kMaybeReg8 ||
- previous_operand_type == OperandType::kReg8 ||
- previous_operand_type == OperandType::kMaybeReg16) &&
- static_cast<uint8_t>(operand_value) == operand_value);
- } else {
- return false;
+ if (previous_operand_type != OperandType::kMaybeReg &&
+ previous_operand_type != OperandType::kReg) {
+ return false;
+ }
}
+ } // Fall-through
+ case OperandType::kFlag8:
+ case OperandType::kIdx:
+ case OperandType::kRuntimeId:
+ case OperandType::kImm: {
+ size_t unsigned_value = static_cast<size_t>(operand_value);
+ return SizeForUnsignedOperand(unsigned_value) <= operand_size;
}
- case OperandType::kIdx16:
- return static_cast<uint16_t>(operand_value) == operand_value;
- case OperandType::kImm8:
- case OperandType::kIdx8:
- return static_cast<uint8_t>(operand_value) == operand_value;
- case OperandType::kMaybeReg8:
+ case OperandType::kMaybeReg:
if (operand_value == 0) {
return true;
}
- // Fall-through to kReg8 case.
- case OperandType::kReg8:
- case OperandType::kRegOut8:
+ // Fall-through to kReg case.
+ case OperandType::kReg:
+ case OperandType::kRegOut:
return RegisterIsValid(Register::FromRawOperand(operand_value),
- operand_type);
- case OperandType::kRegOutPair8:
- case OperandType::kRegOutPair16:
- case OperandType::kRegPair8:
- case OperandType::kRegPair16: {
+ operand_size);
+ case OperandType::kRegOutPair:
+ case OperandType::kRegPair: {
Register reg0 = Register::FromRawOperand(operand_value);
Register reg1 = Register(reg0.index() + 1);
- return RegisterIsValid(reg0, operand_type) &&
- RegisterIsValid(reg1, operand_type);
+ // The size of reg1 is immaterial.
+ return RegisterIsValid(reg0, operand_size) &&
+ RegisterIsValid(reg1, OperandSize::kQuad);
}
- case OperandType::kRegOutTriple8:
- case OperandType::kRegOutTriple16: {
+ case OperandType::kRegOutTriple: {
Register reg0 = Register::FromRawOperand(operand_value);
Register reg1 = Register(reg0.index() + 1);
Register reg2 = Register(reg0.index() + 2);
- return RegisterIsValid(reg0, operand_type) &&
- RegisterIsValid(reg1, operand_type) &&
- RegisterIsValid(reg2, operand_type);
- }
- case OperandType::kMaybeReg16:
- if (operand_value == 0) {
- return true;
- }
- // Fall-through to kReg16 case.
- case OperandType::kReg16:
- case OperandType::kRegOut16: {
- Register reg = Register::FromRawOperand(operand_value);
- return RegisterIsValid(reg, operand_type);
+ // The size of reg1 and reg2 is immaterial.
+ return RegisterIsValid(reg0, operand_size) &&
+ RegisterIsValid(reg1, OperandSize::kQuad) &&
+ RegisterIsValid(reg2, OperandSize::kQuad);
}
}
UNREACHABLE();
return false;
}
-
bool BytecodeArrayBuilder::RegisterIsValid(Register reg,
- OperandType reg_type) const {
+ OperandSize reg_size) const {
if (!reg.is_valid()) {
return false;
}
- switch (Bytecodes::SizeOfOperand(reg_type)) {
- case OperandSize::kByte:
- if (!FitsInReg8OperandUntranslated(reg)) {
- return false;
- }
- break;
- case OperandSize::kShort:
- if (!FitsInReg16OperandUntranslated(reg)) {
- return false;
- }
- break;
- case OperandSize::kNone:
- UNREACHABLE();
- return false;
+ if (SizeForRegisterOperand(reg) > reg_size) {
+ return false;
}
if (reg.is_current_context() || reg.is_function_closure() ||
@@ -1331,15 +1159,10 @@ bool BytecodeArrayBuilder::RegisterIsValid(Register reg,
} else if (reg.is_parameter()) {
int parameter_index = reg.ToParameterIndex(parameter_count());
return parameter_index >= 0 && parameter_index < parameter_count();
- } else if (RegisterTranslator::InTranslationWindow(reg)) {
- return translation_register_count() > 0;
+ } else if (reg.index() < fixed_register_count()) {
+ return true;
} else {
- reg = RegisterTranslator::UntranslateRegister(reg);
- if (reg.index() < fixed_register_count()) {
- return true;
- } else {
- return TemporaryRegisterIsLive(reg);
- }
+ return TemporaryRegisterIsLive(reg);
}
}
@@ -1439,48 +1262,6 @@ Bytecode BytecodeArrayBuilder::BytecodeForCompareOperation(Token::Value op) {
// static
-Bytecode BytecodeArrayBuilder::BytecodeForWideOperands(Bytecode bytecode) {
- switch (bytecode) {
- case Bytecode::kCall:
- return Bytecode::kCallWide;
- case Bytecode::kTailCall:
- return Bytecode::kTailCallWide;
- case Bytecode::kLoadIC:
- return Bytecode::kLoadICWide;
- case Bytecode::kKeyedLoadIC:
- return Bytecode::kKeyedLoadICWide;
- case Bytecode::kStoreICSloppy:
- return Bytecode::kStoreICSloppyWide;
- case Bytecode::kStoreICStrict:
- return Bytecode::kStoreICStrictWide;
- case Bytecode::kKeyedStoreICSloppy:
- return Bytecode::kKeyedStoreICSloppyWide;
- case Bytecode::kKeyedStoreICStrict:
- return Bytecode::kKeyedStoreICStrictWide;
- case Bytecode::kLdaGlobal:
- return Bytecode::kLdaGlobalWide;
- case Bytecode::kLdaGlobalInsideTypeof:
- return Bytecode::kLdaGlobalInsideTypeofWide;
- case Bytecode::kStaGlobalSloppy:
- return Bytecode::kStaGlobalSloppyWide;
- case Bytecode::kStaGlobalStrict:
- return Bytecode::kStaGlobalStrictWide;
- case Bytecode::kLdaLookupSlot:
- return Bytecode::kLdaLookupSlotWide;
- case Bytecode::kLdaLookupSlotInsideTypeof:
- return Bytecode::kLdaLookupSlotInsideTypeofWide;
- case Bytecode::kStaLookupSlotStrict:
- return Bytecode::kStaLookupSlotStrictWide;
- case Bytecode::kStaLookupSlotSloppy:
- return Bytecode::kStaLookupSlotSloppyWide;
- default:
- UNREACHABLE();
- return static_cast<Bytecode>(-1);
- }
-}
-
-
-// static
Bytecode BytecodeArrayBuilder::BytecodeForStoreIC(LanguageMode language_mode) {
switch (language_mode) {
case SLOPPY:
@@ -1588,54 +1369,85 @@ Bytecode BytecodeArrayBuilder::BytecodeForCall(TailCallMode tail_call_mode) {
}
// static
-bool BytecodeArrayBuilder::FitsInIdx8Operand(int value) {
- return kMinUInt8 <= value && value <= kMaxUInt8;
-}
-
-
-// static
-bool BytecodeArrayBuilder::FitsInIdx8Operand(size_t value) {
- return value <= static_cast<size_t>(kMaxUInt8);
+OperandSize BytecodeArrayBuilder::SizeForRegisterOperand(Register value) {
+ if (value.is_byte_operand()) {
+ return OperandSize::kByte;
+ } else if (value.is_short_operand()) {
+ return OperandSize::kShort;
+ } else {
+ return OperandSize::kQuad;
+ }
}
-
// static
-bool BytecodeArrayBuilder::FitsInImm8Operand(int value) {
- return kMinInt8 <= value && value <= kMaxInt8;
+OperandSize BytecodeArrayBuilder::SizeForSignedOperand(int value) {
+ if (kMinInt8 <= value && value <= kMaxInt8) {
+ return OperandSize::kByte;
+ } else if (kMinInt16 <= value && value <= kMaxInt16) {
+ return OperandSize::kShort;
+ } else {
+ return OperandSize::kQuad;
+ }
}
-
// static
-bool BytecodeArrayBuilder::FitsInIdx16Operand(int value) {
- return kMinUInt16 <= value && value <= kMaxUInt16;
+OperandSize BytecodeArrayBuilder::SizeForUnsignedOperand(int value) {
+ DCHECK_GE(value, 0);
+ if (value <= kMaxUInt8) {
+ return OperandSize::kByte;
+ } else if (value <= kMaxUInt16) {
+ return OperandSize::kShort;
+ } else {
+ return OperandSize::kQuad;
+ }
}
-
-// static
-bool BytecodeArrayBuilder::FitsInIdx16Operand(size_t value) {
- return value <= static_cast<size_t>(kMaxUInt16);
+OperandSize BytecodeArrayBuilder::SizeForUnsignedOperand(size_t value) {
+ if (value <= static_cast<size_t>(kMaxUInt8)) {
+ return OperandSize::kByte;
+ } else if (value <= static_cast<size_t>(kMaxUInt16)) {
+ return OperandSize::kShort;
+ } else if (value <= kMaxUInt32) {
+ return OperandSize::kQuad;
+ } else {
+ UNREACHABLE();
+ return OperandSize::kQuad;
+ }
}
-
-// static
-bool BytecodeArrayBuilder::FitsInReg8Operand(Register value) {
- return RegisterTranslator::FitsInReg8Operand(value);
+int BytecodeArrayBuilder::OperandScale(OperandSize size0, OperandSize size1,
+ OperandSize size2, OperandSize size3) {
+ OperandSize upper = std::max(size0, size1);
+ OperandSize lower = std::max(size2, size3);
+ OperandSize result = std::max(upper, lower);
+ DCHECK(result <= OperandSize::kQuad);
+ int operand_scale = static_cast<int>(result);
+ DCHECK(base::bits::IsPowerOfTwo32(static_cast<uint32_t>(operand_scale)));
+ return operand_scale;
}
-// static
-bool BytecodeArrayBuilder::FitsInReg8OperandUntranslated(Register value) {
- return value.is_byte_operand();
+uint32_t BytecodeArrayBuilder::SignedOperand(int value, OperandSize size) {
+ switch (size) {
+ case OperandSize::kByte:
+ return static_cast<uint8_t>(value & 0xff);
+ case OperandSize::kShort:
+ return static_cast<uint16_t>(value & 0xffff);
+ case OperandSize::kQuad:
+ return static_cast<uint32_t>(value);
+ case OperandSize::kNone:
+ UNREACHABLE();
+ }
+ return 0;
}
-
-// static
-bool BytecodeArrayBuilder::FitsInReg16Operand(Register value) {
- return RegisterTranslator::FitsInReg16Operand(value);
+uint32_t BytecodeArrayBuilder::UnsignedOperand(int value) {
+ DCHECK_GE(value, 0);
+ return static_cast<uint32_t>(value);
}
-// static
-bool BytecodeArrayBuilder::FitsInReg16OperandUntranslated(Register value) {
- return value.is_short_operand();
+uint32_t BytecodeArrayBuilder::UnsignedOperand(size_t value) {
+ DCHECK_LE(value, kMaxUInt32);
+ return static_cast<uint32_t>(value);
}
} // namespace interpreter

Powered by Google App Engine
This is Rietveld 408576698