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

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

Issue 1613163002: [interpreter] Wide register support. (Closed) Base URL: https://chromium.googlesource.com/v8/v8.git@master
Patch Set: Added tests, fixed off-by-one error in register indicies. Created 4 years, 11 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 91cfe4df8fa4730c86caa3a5cd7bb958d839ad02..9c47e6beb58b44b9ecfc39e130a5cec136a387cc 100644
--- a/src/interpreter/bytecode-array-builder.cc
+++ b/src/interpreter/bytecode-array-builder.cc
@@ -8,7 +8,7 @@ namespace v8 {
namespace internal {
namespace interpreter {
-class BytecodeArrayBuilder::PreviousBytecodeHelper {
+class BytecodeArrayBuilder::PreviousBytecodeHelper BASE_EMBEDDED {
public:
explicit PreviousBytecodeHelper(const BytecodeArrayBuilder& array_builder)
: array_builder_(array_builder),
@@ -37,9 +37,9 @@ class BytecodeArrayBuilder::PreviousBytecodeHelper {
Bytecodes::GetOperandOffset(bytecode, operand_index);
OperandSize size = Bytecodes::GetOperandSize(bytecode, operand_index);
switch (size) {
- default:
case OperandSize::kNone:
UNREACHABLE();
+ break;
case OperandSize::kByte:
return static_cast<uint32_t>(
array_builder_.bytecodes()->at(operand_offset));
@@ -49,6 +49,7 @@ class BytecodeArrayBuilder::PreviousBytecodeHelper {
array_builder_.bytecodes()->at(operand_offset + 1);
return static_cast<uint32_t>(operand);
}
+ return 0;
}
Handle<Object> GetConstantForIndexOperand(int operand_index) const {
@@ -64,6 +65,39 @@ class BytecodeArrayBuilder::PreviousBytecodeHelper {
};
+class BytecodeArrayBuilder::RegisterTranslationScope BASE_EMBEDDED {
+ public:
+ static const Bytecode kInvalidBytecode = static_cast<Bytecode>(-1);
+
+ RegisterTranslationScope(BytecodeArrayBuilder* builder,
+ Bytecode bytecode = kInvalidBytecode)
+ : builder_(builder), bytecode_(bytecode) {
+ builder->set_register_translation_scope(this);
rmcilroy 2016/01/22 17:50:56 DCHECK_EQ(nullptr, builder()->register_translation
+ }
+
+ ~RegisterTranslationScope() {
+ translator()->CompleteTranslations();
+ builder()->set_register_translation_scope(nullptr);
+ }
+
+ Register Translate(Register reg) {
+ return translator()->Translate(bytecode(), reg);
+ }
+
+ void set_bytecode(Bytecode bytecode) { bytecode_ = bytecode; }
+ Bytecode bytecode() const { return bytecode_; }
+
+ private:
+ BytecodeArrayBuilder* builder() const { return builder_; }
+ RegisterTranslator* translator() { return builder()->register_translator(); }
+
+ BytecodeArrayBuilder* builder_;
+ Bytecode bytecode_;
+
+ DISALLOW_COPY_AND_ASSIGN(RegisterTranslationScope);
+};
+
+
BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone)
: isolate_(isolate),
zone_(zone),
@@ -79,7 +113,9 @@ BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone)
local_register_count_(-1),
context_register_count_(-1),
temporary_register_count_(0),
- free_temporaries_(zone) {}
+ free_temporaries_(zone),
+ register_translator_(this),
+ register_translation_scope_(nullptr) {}
BytecodeArrayBuilder::~BytecodeArrayBuilder() { DCHECK_EQ(0, unbound_jumps_); }
@@ -148,7 +184,8 @@ Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() {
EnsureReturn();
int bytecode_size = static_cast<int>(bytecodes_.size());
- int register_count = fixed_register_count() + temporary_register_count_;
+ int register_count =
+ fixed_and_temporary_register_count() + translation_register_count();
int frame_size = register_count * kPointerSize;
Handle<FixedArray> constant_pool = constant_array_builder()->ToFixedArray();
Handle<FixedArray> handler_table = handler_table_builder()->ToHandlerTable();
@@ -167,6 +204,13 @@ void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t(&operands)[N]) {
if (exit_seen_in_block_) return;
DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), static_cast<int>(N));
+ DCHECK((register_translation_scope() == nullptr &&
+ Bytecodes::NumberOfRegisterOperands(bytecode) == 0) ||
+ (register_translation_scope() != nullptr &&
+ Bytecodes::NumberOfRegisterOperands(bytecode) > 0));
+ DCHECK(register_translator()->RegisterOperandsValid(bytecode, operands,
+ static_cast<int>(N)));
+
last_bytecode_start_ = bytecodes()->size();
bytecodes()->push_back(Bytecodes::ToByte(bytecode));
for (int i = 0; i < static_cast<int>(N); i++) {
@@ -174,6 +218,7 @@ void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t(&operands)[N]) {
switch (Bytecodes::GetOperandSize(bytecode, i)) {
case OperandSize::kNone:
UNREACHABLE();
+ break;
case OperandSize::kByte:
bytecodes()->push_back(static_cast<uint8_t>(operands[i]));
break;
@@ -234,7 +279,9 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op,
UNIMPLEMENTED();
}
- Output(BytecodeForBinaryOperation(op), reg.ToRawOperand());
+ RegisterTranslationScope translator(this, BytecodeForBinaryOperation(op));
+ reg = translator.Translate(reg);
+ Output(translator.bytecode(), reg.ToRawOperand());
rmcilroy 2016/01/22 17:50:56 To avoid the extra translate call, could we write
return *this;
}
@@ -268,7 +315,9 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation(
UNIMPLEMENTED();
}
- Output(BytecodeForCompareOperation(op), reg.ToRawOperand());
+ RegisterTranslationScope translator(this, BytecodeForCompareOperation(op));
+ reg = translator.Translate(reg);
+ Output(translator.bytecode(), reg.ToRawOperand());
return *this;
}
@@ -342,8 +391,10 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadBooleanConstant(bool value) {
BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister(
Register reg) {
+ RegisterTranslationScope translator(this, Bytecode::kLdar);
+ reg = translator.Translate(reg);
if (!IsRegisterInAccumulator(reg)) {
- Output(Bytecode::kLdar, reg.ToRawOperand());
+ Output(translator.bytecode(), reg.ToRawOperand());
}
return *this;
}
@@ -351,8 +402,10 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister(
BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister(
Register reg) {
+ RegisterTranslationScope translator(this, Bytecode::kStar);
+ reg = translator.Translate(reg);
if (!IsRegisterInAccumulator(reg)) {
- Output(Bytecode::kStar, reg.ToRawOperand());
+ Output(translator.bytecode(), reg.ToRawOperand());
}
return *this;
}
@@ -361,17 +414,42 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister(
BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from,
Register to) {
DCHECK(from != to);
- if (FitsInReg8Operand(to) && FitsInReg8Operand(from)) {
- Output(Bytecode::kMov, from.ToRawOperand(), to.ToRawOperand());
- } else if (FitsInReg16Operand(to) && FitsInReg16Operand(from)) {
- Output(Bytecode::kMovWide, from.ToRawOperand(), to.ToRawOperand());
+ RegisterTranslationScope translator(this);
rmcilroy 2016/01/22 17:50:56 Personally I would prefer that the RegisterTransla
+ if (FitsInReg8Operand(from) && FitsInReg8Operand(to)) {
+ translator.set_bytecode(Bytecode::kMov);
+ } else if (FitsInReg16Operand(from) && FitsInReg16Operand(to)) {
+ translator.set_bytecode(Bytecode::kMovWide);
} else {
UNIMPLEMENTED();
}
+ from = translator.Translate(from);
+ to = translator.Translate(to);
+ Output(translator.bytecode(), from.ToRawOperand(), to.ToRawOperand());
return *this;
}
+bool BytecodeArrayBuilder::MoveRegisterUntranslated(Register from,
+ Register to) {
+ if (!from.is_valid() || !to.is_valid()) {
rmcilroy 2016/01/22 17:50:56 Just DCHECK(from.is_valid() && to.is_valid)) ?
+ UNIMPLEMENTED();
+ return false;
+ }
+
+ DCHECK(FitsInReg8OperandUntranslated(from) ||
+ FitsInReg8OperandUntranslated(to));
+ DCHECK(from != to);
+ if (FitsInReg16OperandUntranslated(from) &&
+ FitsInReg16OperandUntranslated(to)) {
+ Output(Bytecode::kMovWide, from.ToRawOperand(), to.ToRawOperand());
+ return true;
+ } else {
+ UNIMPLEMENTED();
+ return false;
+ }
+}
+
+
BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal(
const Handle<String> name, int feedback_slot, LanguageMode language_mode,
TypeofMode typeof_mode) {
@@ -414,15 +492,17 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::StoreGlobal(
BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context,
int slot_index) {
DCHECK(slot_index >= 0);
+ RegisterTranslationScope translator(this);
if (FitsInIdx8Operand(slot_index)) {
- Output(Bytecode::kLdaContextSlot, context.ToRawOperand(),
- static_cast<uint8_t>(slot_index));
+ translator.set_bytecode(Bytecode::kLdaContextSlot);
} else if (FitsInIdx16Operand(slot_index)) {
- Output(Bytecode::kLdaContextSlotWide, context.ToRawOperand(),
- static_cast<uint16_t>(slot_index));
+ translator.set_bytecode(Bytecode::kLdaContextSlotWide);
} else {
UNIMPLEMENTED();
}
+ context = translator.Translate(context);
+ Output(translator.bytecode(), context.ToRawOperand(),
+ static_cast<uint16_t>(slot_index));
return *this;
}
@@ -430,15 +510,17 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context,
BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context,
int slot_index) {
DCHECK(slot_index >= 0);
+ RegisterTranslationScope translator(this);
if (FitsInIdx8Operand(slot_index)) {
- Output(Bytecode::kStaContextSlot, context.ToRawOperand(),
- static_cast<uint8_t>(slot_index));
+ translator.set_bytecode(Bytecode::kStaContextSlot);
} else if (FitsInIdx16Operand(slot_index)) {
- Output(Bytecode::kStaContextSlotWide, context.ToRawOperand(),
- static_cast<uint16_t>(slot_index));
+ translator.set_bytecode(Bytecode::kStaContextSlotWide);
} else {
UNIMPLEMENTED();
}
+ context = translator.Translate(context);
+ Output(translator.bytecode(), context.ToRawOperand(),
+ static_cast<uint16_t>(slot_index));
return *this;
}
@@ -480,35 +562,39 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::StoreLookupSlot(
BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty(
Register object, const Handle<String> name, int feedback_slot,
LanguageMode language_mode) {
- Bytecode bytecode = BytecodeForLoadIC(language_mode);
+ RegisterTranslationScope translator(this);
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));
+ translator.set_bytecode(BytecodeForLoadIC(language_mode));
} 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));
+ translator.set_bytecode(
+ BytecodeForWideOperands(BytecodeForLoadIC(language_mode)));
} else {
UNIMPLEMENTED();
}
+ object = translator.Translate(object);
+ Output(translator.bytecode(), object.ToRawOperand(),
+ static_cast<uint16_t>(name_index),
+ static_cast<uint16_t>(feedback_slot));
rmcilroy 2016/01/22 17:50:56 Maybe just cast directly to uint32_t now so that w
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty(
Register object, int feedback_slot, LanguageMode language_mode) {
- Bytecode bytecode = BytecodeForKeyedLoadIC(language_mode);
+ RegisterTranslationScope translator(this);
if (FitsInIdx8Operand(feedback_slot)) {
- Output(bytecode, object.ToRawOperand(),
- static_cast<uint8_t>(feedback_slot));
+ translator.set_bytecode(BytecodeForKeyedLoadIC(language_mode));
} else if (FitsInIdx16Operand(feedback_slot)) {
- Output(BytecodeForWideOperands(bytecode), object.ToRawOperand(),
- static_cast<uint16_t>(feedback_slot));
+ translator.set_bytecode(
+ BytecodeForWideOperands(BytecodeForKeyedLoadIC(language_mode)));
} else {
UNIMPLEMENTED();
}
+ object = translator.Translate(object);
+ Output(translator.bytecode(), object.ToRawOperand(),
+ static_cast<uint16_t>(feedback_slot));
return *this;
}
@@ -516,19 +602,21 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty(
BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty(
Register object, const Handle<String> name, int feedback_slot,
LanguageMode language_mode) {
- Bytecode bytecode = BytecodeForStoreIC(language_mode);
size_t name_index = GetConstantPoolEntry(name);
+ RegisterTranslationScope translator(this);
if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) {
- Output(bytecode, object.ToRawOperand(), static_cast<uint8_t>(name_index),
- static_cast<uint8_t>(feedback_slot));
+ translator.set_bytecode(BytecodeForStoreIC(language_mode));
} 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));
+ translator.set_bytecode(
+ BytecodeForWideOperands(BytecodeForStoreIC(language_mode)));
} else {
UNIMPLEMENTED();
}
+ object = translator.Translate(object);
+ Output(translator.bytecode(), object.ToRawOperand(),
+ static_cast<uint16_t>(name_index),
+ static_cast<uint16_t>(feedback_slot));
return *this;
}
@@ -536,16 +624,19 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty(
BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty(
Register object, Register key, int feedback_slot,
LanguageMode language_mode) {
- Bytecode bytecode = BytecodeForKeyedStoreIC(language_mode);
+ RegisterTranslationScope translator(this);
if (FitsInIdx8Operand(feedback_slot)) {
- Output(bytecode, object.ToRawOperand(), key.ToRawOperand(),
- static_cast<uint8_t>(feedback_slot));
+ translator.set_bytecode(BytecodeForKeyedStoreIC(language_mode));
} else if (FitsInIdx16Operand(feedback_slot)) {
- Output(BytecodeForWideOperands(bytecode), object.ToRawOperand(),
- key.ToRawOperand(), static_cast<uint16_t>(feedback_slot));
+ translator.set_bytecode(
+ BytecodeForWideOperands(BytecodeForKeyedStoreIC(language_mode)));
} else {
UNIMPLEMENTED();
}
+ object = translator.Translate(object);
+ key = translator.Translate(key);
+ Output(translator.bytecode(), object.ToRawOperand(), key.ToRawOperand(),
+ static_cast<uint16_t>(feedback_slot));
return *this;
}
@@ -640,13 +731,17 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CreateObjectLiteral(
BytecodeArrayBuilder& BytecodeArrayBuilder::PushContext(Register context) {
- Output(Bytecode::kPushContext, context.ToRawOperand());
+ RegisterTranslationScope translator(this, Bytecode::kPushContext);
+ context = translator.Translate(context);
+ Output(translator.bytecode(), context.ToRawOperand());
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) {
- Output(Bytecode::kPopContext, context.ToRawOperand());
+ RegisterTranslationScope translator(this, Bytecode::kPopContext);
+ context = translator.Translate(context);
+ Output(translator.bytecode(), context.ToRawOperand());
return *this;
}
@@ -969,20 +1064,26 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::Return() {
BytecodeArrayBuilder& BytecodeArrayBuilder::ForInPrepare(
Register cache_info_triple) {
+ RegisterTranslationScope translator(this);
if (FitsInReg8Operand(cache_info_triple)) {
- Output(Bytecode::kForInPrepare, cache_info_triple.ToRawOperand());
+ translator.set_bytecode(Bytecode::kForInPrepare);
} else if (FitsInReg16Operand(cache_info_triple)) {
- Output(Bytecode::kForInPrepareWide, cache_info_triple.ToRawOperand());
+ translator.set_bytecode(Bytecode::kForInPrepareWide);
} else {
UNIMPLEMENTED();
}
+ cache_info_triple = translator.Translate(cache_info_triple);
+ Output(translator.bytecode(), cache_info_triple.ToRawOperand());
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::ForInDone(Register index,
Register cache_length) {
- Output(Bytecode::kForInDone, index.ToRawOperand(),
+ RegisterTranslationScope translator(this, Bytecode::kForInDone);
+ index = translator.Translate(index);
+ cache_length = translator.Translate(cache_length);
+ Output(translator.bytecode(), index.ToRawOperand(),
cache_length.ToRawOperand());
return *this;
}
@@ -990,23 +1091,29 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::ForInDone(Register index,
BytecodeArrayBuilder& BytecodeArrayBuilder::ForInNext(
Register receiver, Register index, Register cache_type_array_pair) {
+ RegisterTranslationScope translator(this);
if (FitsInReg8Operand(receiver) && FitsInReg8Operand(index) &&
FitsInReg8Operand(cache_type_array_pair)) {
- Output(Bytecode::kForInNext, receiver.ToRawOperand(), index.ToRawOperand(),
- cache_type_array_pair.ToRawOperand());
+ translator.set_bytecode(Bytecode::kForInNext);
} else if (FitsInReg16Operand(receiver) && FitsInReg16Operand(index) &&
FitsInReg16Operand(cache_type_array_pair)) {
- Output(Bytecode::kForInNextWide, receiver.ToRawOperand(),
- index.ToRawOperand(), cache_type_array_pair.ToRawOperand());
+ translator.set_bytecode(Bytecode::kForInNextWide);
} else {
UNIMPLEMENTED();
}
+ receiver = translator.Translate(receiver);
+ index = translator.Translate(index);
+ cache_type_array_pair = translator.Translate(cache_type_array_pair);
+ Output(translator.bytecode(), receiver.ToRawOperand(), index.ToRawOperand(),
+ cache_type_array_pair.ToRawOperand());
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::ForInStep(Register index) {
- Output(Bytecode::kForInStep, index.ToRawOperand());
+ RegisterTranslationScope translator(this, Bytecode::kForInStep);
+ index = translator.Translate(index);
+ Output(translator.bytecode(), index.ToRawOperand());
return *this;
}
@@ -1051,20 +1158,22 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable,
Register receiver,
size_t arg_count,
int feedback_slot) {
+ RegisterTranslationScope translator(this);
if (FitsInReg8Operand(callable) && FitsInReg8Operand(receiver) &&
FitsInIdx8Operand(arg_count) && FitsInIdx8Operand(feedback_slot)) {
- Output(Bytecode::kCall, callable.ToRawOperand(), receiver.ToRawOperand(),
- static_cast<uint8_t>(arg_count),
- static_cast<uint8_t>(feedback_slot));
+ translator.set_bytecode(Bytecode::kCall);
} else if (FitsInReg16Operand(callable) && FitsInReg16Operand(receiver) &&
FitsInIdx16Operand(arg_count) &&
FitsInIdx16Operand(feedback_slot)) {
- Output(Bytecode::kCallWide, callable.ToRawOperand(),
- receiver.ToRawOperand(), static_cast<uint16_t>(arg_count),
- static_cast<uint16_t>(feedback_slot));
+ translator.set_bytecode(Bytecode::kCallWide);
} else {
UNIMPLEMENTED();
}
+ callable = translator.Translate(callable);
+ receiver = translator.Translate(receiver);
+ Output(translator.bytecode(), callable.ToRawOperand(),
+ receiver.ToRawOperand(), static_cast<uint16_t>(arg_count),
+ static_cast<uint16_t>(feedback_slot));
return *this;
}
@@ -1077,17 +1186,20 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor,
first_arg = Register(0);
}
+ RegisterTranslationScope translator(this);
if (FitsInReg8Operand(constructor) && FitsInReg8Operand(first_arg) &&
FitsInIdx8Operand(arg_count)) {
- Output(Bytecode::kNew, constructor.ToRawOperand(), first_arg.ToRawOperand(),
- static_cast<uint8_t>(arg_count));
+ translator.set_bytecode(Bytecode::kNew);
} else if (FitsInReg16Operand(constructor) && FitsInReg16Operand(first_arg) &&
FitsInIdx16Operand(arg_count)) {
- Output(Bytecode::kNewWide, constructor.ToRawOperand(),
- first_arg.ToRawOperand(), static_cast<uint16_t>(arg_count));
+ translator.set_bytecode(Bytecode::kNewWide);
} else {
UNIMPLEMENTED();
}
+ constructor = translator.Translate(constructor);
+ first_arg = translator.Translate(first_arg);
+ Output(translator.bytecode(), constructor.ToRawOperand(),
+ first_arg.ToRawOperand(), static_cast<uint16_t>(arg_count));
return *this;
}
@@ -1100,15 +1212,18 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime(
DCHECK_EQ(0u, arg_count);
first_arg = Register(0);
}
+
+ RegisterTranslationScope translator(this);
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));
+ translator.set_bytecode(Bytecode::kCallRuntime);
} 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));
+ translator.set_bytecode(Bytecode::kCallRuntimeWide);
} else {
UNIMPLEMENTED();
}
+ first_arg = translator.Translate(first_arg);
+ Output(translator.bytecode(), static_cast<uint16_t>(function_id),
+ first_arg.ToRawOperand(), static_cast<uint16_t>(arg_count));
return *this;
}
@@ -1122,19 +1237,22 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntimeForPair(
DCHECK_EQ(0u, arg_count);
first_arg = Register(0);
}
+
+ RegisterTranslationScope translator(this);
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());
+ translator.set_bytecode(Bytecode::kCallRuntimeForPair);
} 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());
+ translator.set_bytecode(Bytecode::kCallRuntimeForPairWide);
} else {
UNIMPLEMENTED();
}
+ first_arg = translator.Translate(first_arg);
+ first_return = translator.Translate(first_return);
+ Output(translator.bytecode(), static_cast<uint16_t>(function_id),
+ first_arg.ToRawOperand(), static_cast<uint16_t>(arg_count),
+ first_return.ToRawOperand());
return *this;
}
@@ -1143,22 +1261,27 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime(int context_index,
Register receiver,
size_t arg_count) {
DCHECK(FitsInIdx16Operand(context_index));
+
+ RegisterTranslationScope translator(this);
if (FitsInReg8Operand(receiver) && FitsInIdx8Operand(arg_count)) {
- Output(Bytecode::kCallJSRuntime, static_cast<uint16_t>(context_index),
- receiver.ToRawOperand(), static_cast<uint8_t>(arg_count));
+ translator.set_bytecode(Bytecode::kCallJSRuntime);
} else if (FitsInReg16Operand(receiver) && FitsInIdx16Operand(arg_count)) {
- Output(Bytecode::kCallJSRuntimeWide, static_cast<uint16_t>(context_index),
- receiver.ToRawOperand(), static_cast<uint16_t>(arg_count));
+ translator.set_bytecode(Bytecode::kCallJSRuntimeWide);
} else {
UNIMPLEMENTED();
}
+ receiver = translator.Translate(receiver);
+ Output(translator.bytecode(), static_cast<uint16_t>(context_index),
+ receiver.ToRawOperand(), static_cast<uint16_t>(arg_count));
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object,
LanguageMode language_mode) {
- Output(BytecodeForDelete(language_mode), object.ToRawOperand());
+ RegisterTranslationScope translator(this, BytecodeForDelete(language_mode));
+ object = translator.Translate(object);
+ Output(translator.bytecode(), object.ToRawOperand());
return *this;
}
@@ -1174,9 +1297,14 @@ size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) {
}
+void BytecodeArrayBuilder::ForgeTemporaryRegister() {
+ temporary_register_count_++;
+}
+
+
int BytecodeArrayBuilder::BorrowTemporaryRegister() {
if (free_temporaries_.empty()) {
- temporary_register_count_ += 1;
+ ForgeTemporaryRegister();
return last_temporary_register().index();
} else {
auto pos = free_temporaries_.begin();
@@ -1195,7 +1323,7 @@ int BytecodeArrayBuilder::BorrowTemporaryRegisterNotInRange(int start_index,
// greater than end_index.
index = free_temporaries_.upper_bound(end_index);
if (index == free_temporaries_.end()) {
- temporary_register_count_ += 1;
+ ForgeTemporaryRegister();
return last_temporary_register().index();
}
} else {
@@ -1227,11 +1355,29 @@ int BytecodeArrayBuilder::PrepareForConsecutiveTemporaryRegisters(
return -1;
}
+ // TODO(oth): replace use of set<> here for free_temporaries with a
+ // more efficient structure. And/or partition into two searches -
+ // one before the translation window and one after.
+ if (free_temporaries_.empty()) {
rmcilroy 2016/01/22 17:50:56 Please add a comment on why you are having to forg
+ ForgeTemporaryRegister();
+ free_temporaries_.insert(last_temporary_register().index());
+ }
+
// Search within existing temporaries for a run.
auto start = free_temporaries_.begin();
size_t run_length = 0;
for (auto run_end = start; run_end != free_temporaries_.end(); run_end++) {
- if (*run_end != *start + static_cast<int>(run_length)) {
+ int expected = *start + static_cast<int>(run_length);
+ if (*run_end != expected) {
+ start = run_end;
+ run_length = 0;
+ }
+ Register reg_start(*start);
+ Register reg_expected(expected);
+ if (RegisterTranslator::DistanceToTranslationWindow(reg_start) > 0 &&
+ RegisterTranslator::DistanceToTranslationWindow(reg_expected) <= 0) {
+ // Run straddles the translation window boundary where there is
+ // a hidden discontinuity.
rmcilroy 2016/01/22 17:50:56 /s/discontinuity/hole in allocatable registers ?
start = run_end;
run_length = 0;
}
@@ -1248,12 +1394,34 @@ int BytecodeArrayBuilder::PrepareForConsecutiveTemporaryRegisters(
run_length = 0;
}
+ // Pad temporaries if extended run would cross translation boundary.
+ Register reg_first(*start);
+ Register reg_last(*start + static_cast<int>(count) - 1);
+ DCHECK_GT(RegisterTranslator::DistanceToTranslationWindow(reg_first),
+ RegisterTranslator::DistanceToTranslationWindow(reg_last));
+ while (RegisterTranslator::DistanceToTranslationWindow(reg_first) > 0 &&
+ RegisterTranslator::DistanceToTranslationWindow(reg_last) <= 0) {
+ ForgeTemporaryRegister();
+ free_temporaries_.insert(last_temporary_register().index());
+ start = --free_temporaries_.end();
+ reg_first = Register(*start);
+ reg_last = Register(*start + static_cast<int>(count) - 1);
+ run_length = 0;
+ }
+
// Ensure enough registers for run.
while (run_length++ < count) {
- temporary_register_count_++;
+ ForgeTemporaryRegister();
free_temporaries_.insert(last_temporary_register().index());
}
- return last_temporary_register().index() - static_cast<int>(count) + 1;
+
+ int run_start =
+ last_temporary_register().index() - static_cast<int>(count) + 1;
+ DCHECK(RegisterTranslator::DistanceToTranslationWindow(Register(run_start)) <=
+ 0 ||
+ RegisterTranslator::DistanceToTranslationWindow(
+ Register(run_start + static_cast<int>(count) - 1)) > 0);
+ return run_start;
}
@@ -1324,10 +1492,14 @@ bool BytecodeArrayBuilder::RegisterIsValid(Register reg,
OperandType reg_type) const {
switch (Bytecodes::SizeOfOperand(reg_type)) {
case OperandSize::kByte:
- if (!FitsInReg8Operand(reg)) { return false; }
+ if (!FitsInReg8OperandUntranslated(reg)) {
+ return false;
+ }
break;
case OperandSize::kShort:
- if (!FitsInReg16Operand(reg)) { return false; }
+ if (!FitsInReg16OperandUntranslated(reg)) {
+ return false;
+ }
break;
case OperandSize::kNone:
UNREACHABLE();
@@ -1340,10 +1512,15 @@ 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 (reg.index() < fixed_register_count()) {
- return true;
+ } else if (translation_register_count() == 0) {
+ if (reg.index() < fixed_register_count()) {
+ return true;
+ } else {
+ return TemporaryRegisterIsLive(reg);
+ }
} else {
- return TemporaryRegisterIsLive(reg);
+ return reg.index() < (fixed_and_temporary_register_count() +
+ translation_register_count());
rmcilroy 2016/01/22 17:50:56 Does this not check for the temp being live. Could
}
}
@@ -1358,9 +1535,10 @@ bool BytecodeArrayBuilder::IsRegisterInAccumulator(Register reg) {
if (LastBytecodeInSameBlock()) {
PreviousBytecodeHelper previous_bytecode(*this);
Bytecode bytecode = previous_bytecode.GetBytecode();
- if ((bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar) &&
- (reg == Register::FromOperand(previous_bytecode.GetOperand(0)))) {
- return true;
+ if (bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar) {
+ Register previous =
rmcilroy 2016/01/22 17:50:56 nit - previous_reg
+ Register::FromOperand(previous_bytecode.GetOperand(0));
+ return previous == reg;
}
}
return false;
@@ -1673,13 +1851,25 @@ bool BytecodeArrayBuilder::FitsInIdx16Operand(size_t value) {
// static
bool BytecodeArrayBuilder::FitsInReg8Operand(Register value) {
- return kMinInt8 <= value.index() && value.index() <= kMaxInt8;
+ return RegisterTranslator::FitsInReg8Operand(value);
+}
+
+
+// static
+bool BytecodeArrayBuilder::FitsInReg8OperandUntranslated(Register value) {
+ return value.is_byte_operand();
}
// static
bool BytecodeArrayBuilder::FitsInReg16Operand(Register value) {
- return kMinInt16 <= value.index() && value.index() <= kMaxInt16;
+ return RegisterTranslator::FitsInReg16Operand(value);
+}
+
+
+// static
+bool BytecodeArrayBuilder::FitsInReg16OperandUntranslated(Register value) {
+ return value.is_short_operand();
}
} // namespace interpreter

Powered by Google App Engine
This is Rietveld 408576698