Revert "Revert "Upgrade to 5.0.71.48"" DO NOT MERGE
This reverts commit f2e3994fa5148cc3d9946666f0b0596290192b0e,
and updates the x64 makefile properly so it doesn't break that
build.
FPIIM-449
Change-Id: Ib83e35bfbae6af627451c926a9650ec57c045605
(cherry picked from commit 109988c7ccb6f3fd1a58574fa3dfb88beaef6632)
diff --git a/src/interpreter/bytecode-array-builder.cc b/src/interpreter/bytecode-array-builder.cc
index 1b15fc6..7103c72 100644
--- a/src/interpreter/bytecode-array-builder.cc
+++ b/src/interpreter/bytecode-array-builder.cc
@@ -3,12 +3,13 @@
// found in the LICENSE file.
#include "src/interpreter/bytecode-array-builder.h"
+#include "src/compiler.h"
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 +38,9 @@
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 +50,7 @@
array_builder_.bytecodes()->at(operand_offset + 1);
return static_cast<uint32_t>(operand);
}
+ return 0;
}
Handle<Object> GetConstantForIndexOperand(int operand_index) const {
@@ -63,43 +65,31 @@
DISALLOW_COPY_AND_ASSIGN(PreviousBytecodeHelper);
};
-
-BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone)
+BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone,
+ int parameter_count,
+ int context_count, int locals_count)
: isolate_(isolate),
zone_(zone),
bytecodes_(zone),
bytecode_generated_(false),
constant_array_builder_(isolate, zone),
+ handler_table_builder_(isolate, zone),
+ source_position_table_builder_(isolate, zone),
last_block_end_(0),
last_bytecode_start_(~0),
exit_seen_in_block_(false),
unbound_jumps_(0),
- parameter_count_(-1),
- local_register_count_(-1),
- context_register_count_(-1),
- temporary_register_count_(0),
- free_temporaries_(zone) {}
-
-
-BytecodeArrayBuilder::~BytecodeArrayBuilder() { DCHECK_EQ(0, unbound_jumps_); }
-
-
-void BytecodeArrayBuilder::set_locals_count(int number_of_locals) {
- local_register_count_ = number_of_locals;
- DCHECK_LE(context_register_count_, 0);
-}
-
-
-void BytecodeArrayBuilder::set_parameter_count(int number_of_parameters) {
- parameter_count_ = number_of_parameters;
-}
-
-
-void BytecodeArrayBuilder::set_context_count(int number_of_contexts) {
- context_register_count_ = number_of_contexts;
+ parameter_count_(parameter_count),
+ local_register_count_(locals_count),
+ context_register_count_(context_count),
+ temporary_allocator_(zone, fixed_register_count()),
+ register_translator_(this) {
+ DCHECK_GE(parameter_count_, 0);
+ DCHECK_GE(context_register_count_, 0);
DCHECK_GE(local_register_count_, 0);
}
+BytecodeArrayBuilder::~BytecodeArrayBuilder() { DCHECK_EQ(0, unbound_jumps_); }
Register BytecodeArrayBuilder::first_context_register() const {
DCHECK_GT(context_register_count_, 0);
@@ -113,18 +103,6 @@
}
-Register BytecodeArrayBuilder::first_temporary_register() const {
- DCHECK_GT(temporary_register_count_, 0);
- return Register(fixed_register_count());
-}
-
-
-Register BytecodeArrayBuilder::last_temporary_register() const {
- DCHECK_GT(temporary_register_count_, 0);
- return Register(fixed_register_count() + temporary_register_count_ - 1);
-}
-
-
Register BytecodeArrayBuilder::Parameter(int parameter_index) const {
DCHECK_GE(parameter_index, 0);
return Register::FromParameterIndex(parameter_index, parameter_count());
@@ -136,25 +114,23 @@
}
-bool BytecodeArrayBuilder::RegisterIsTemporary(Register reg) const {
- return temporary_register_count_ > 0 && first_temporary_register() <= reg &&
- reg <= last_temporary_register();
-}
-
-
Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() {
DCHECK_EQ(bytecode_generated_, false);
- EnsureReturn();
+ DCHECK(exit_seen_in_block_);
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;
- Factory* factory = isolate_->factory();
- Handle<FixedArray> constant_pool =
- constant_array_builder()->ToFixedArray(factory);
- Handle<BytecodeArray> output =
- factory->NewBytecodeArray(bytecode_size, &bytecodes_.front(), frame_size,
- parameter_count(), constant_pool);
+ Handle<FixedArray> constant_pool = constant_array_builder()->ToFixedArray();
+ Handle<FixedArray> handler_table = handler_table_builder()->ToHandlerTable();
+ Handle<FixedArray> source_position_table =
+ source_position_table_builder()->ToFixedArray();
+ Handle<BytecodeArray> output = isolate_->factory()->NewBytecodeArray(
+ bytecode_size, &bytecodes_.front(), frame_size, parameter_count(),
+ constant_pool);
+ output->set_handler_table(*handler_table);
+ output->set_source_position_table(*source_position_table);
bytecode_generated_ = true;
return output;
}
@@ -163,16 +139,28 @@
template <size_t N>
void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t(&operands)[N]) {
// Don't output dead code.
- if (exit_seen_in_block_) return;
+ if (exit_seen_in_block_) {
+ source_position_table_builder_.RevertPosition(bytecodes()->size());
+ return;
+ }
- DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), static_cast<int>(N));
+ 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();
bytecodes()->push_back(Bytecodes::ToByte(bytecode));
- for (int i = 0; i < static_cast<int>(N); i++) {
+ for (int i = 0; i < operand_count; i++) {
DCHECK(OperandIsValid(bytecode, i, operands[i]));
switch (Bytecodes::GetOperandSize(bytecode, i)) {
case OperandSize::kNone:
UNREACHABLE();
+ break;
case OperandSize::kByte:
bytecodes()->push_back(static_cast<uint8_t>(operands[i]));
break;
@@ -185,6 +173,10 @@
}
}
}
+
+ if (register_operand_count > 0) {
+ register_translator()->TranslateOutputRegisters();
+ }
}
@@ -218,32 +210,23 @@
void BytecodeArrayBuilder::Output(Bytecode bytecode) {
// Don't output dead code.
- if (exit_seen_in_block_) return;
+ if (exit_seen_in_block_) {
+ source_position_table_builder_.RevertPosition(bytecodes()->size());
+ return;
+ }
DCHECK_EQ(Bytecodes::NumberOfOperands(bytecode), 0);
last_bytecode_start_ = bytecodes()->size();
bytecodes()->push_back(Bytecodes::ToByte(bytecode));
}
-
BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op,
- Register reg,
- Strength strength) {
- if (is_strong(strength)) {
- UNIMPLEMENTED();
- }
-
- Output(BytecodeForBinaryOperation(op), reg.ToOperand());
+ Register reg) {
+ Output(BytecodeForBinaryOperation(op), reg.ToRawOperand());
return *this;
}
-
-BytecodeArrayBuilder& BytecodeArrayBuilder::CountOperation(Token::Value op,
- Strength strength) {
- if (is_strong(strength)) {
- UNIMPLEMENTED();
- }
-
+BytecodeArrayBuilder& BytecodeArrayBuilder::CountOperation(Token::Value op) {
Output(BytecodeForCountOperation(op));
return *this;
}
@@ -260,14 +243,9 @@
return *this;
}
-
-BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation(
- Token::Value op, Register reg, Strength strength) {
- if (is_strong(strength)) {
- UNIMPLEMENTED();
- }
-
- Output(BytecodeForCompareOperation(op), reg.ToOperand());
+BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation(Token::Value op,
+ Register reg) {
+ Output(BytecodeForCompareOperation(op), reg.ToRawOperand());
return *this;
}
@@ -338,11 +316,10 @@
return *this;
}
-
BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister(
Register reg) {
if (!IsRegisterInAccumulator(reg)) {
- Output(Bytecode::kLdar, reg.ToOperand());
+ Output(Bytecode::kLdar, reg.ToRawOperand());
}
return *this;
}
@@ -350,15 +327,8 @@
BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister(
Register reg) {
- // TODO(oth): Avoid storing the accumulator in the register if the
- // previous bytecode loaded the accumulator with the same register.
- //
- // TODO(oth): If the previous bytecode is a MOV into this register,
- // the previous instruction can be removed. The logic for determining
- // these redundant MOVs appears complex.
- Output(Bytecode::kStar, reg.ToOperand());
if (!IsRegisterInAccumulator(reg)) {
- Output(Bytecode::kStar, reg.ToOperand());
+ Output(Bytecode::kStar, reg.ToRawOperand());
}
return *this;
}
@@ -367,31 +337,37 @@
BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from,
Register to) {
DCHECK(from != to);
- Output(Bytecode::kMov, from.ToOperand(), to.ToOperand());
- return *this;
-}
-
-
-BytecodeArrayBuilder& BytecodeArrayBuilder::ExchangeRegisters(Register reg0,
- Register reg1) {
- DCHECK(reg0 != reg1);
- if (FitsInReg8Operand(reg0)) {
- Output(Bytecode::kExchange, reg0.ToOperand(), reg1.ToWideOperand());
- } else if (FitsInReg8Operand(reg1)) {
- Output(Bytecode::kExchange, reg1.ToOperand(), reg0.ToWideOperand());
+ 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 {
- Output(Bytecode::kExchangeWide, reg0.ToWideOperand(), reg1.ToWideOperand());
+ UNIMPLEMENTED();
}
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, LanguageMode language_mode,
- TypeofMode typeof_mode) {
- // TODO(rmcilroy): Potentially store language and typeof information in an
+ 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(language_mode, typeof_mode);
+ 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),
@@ -429,10 +405,10 @@
int slot_index) {
DCHECK(slot_index >= 0);
if (FitsInIdx8Operand(slot_index)) {
- Output(Bytecode::kLdaContextSlot, context.ToOperand(),
+ Output(Bytecode::kLdaContextSlot, context.ToRawOperand(),
static_cast<uint8_t>(slot_index));
} else if (FitsInIdx16Operand(slot_index)) {
- Output(Bytecode::kLdaContextSlotWide, context.ToOperand(),
+ Output(Bytecode::kLdaContextSlotWide, context.ToRawOperand(),
static_cast<uint16_t>(slot_index));
} else {
UNIMPLEMENTED();
@@ -445,10 +421,10 @@
int slot_index) {
DCHECK(slot_index >= 0);
if (FitsInIdx8Operand(slot_index)) {
- Output(Bytecode::kStaContextSlot, context.ToOperand(),
+ Output(Bytecode::kStaContextSlot, context.ToRawOperand(),
static_cast<uint8_t>(slot_index));
} else if (FitsInIdx16Operand(slot_index)) {
- Output(Bytecode::kStaContextSlotWide, context.ToOperand(),
+ Output(Bytecode::kStaContextSlotWide, context.ToRawOperand(),
static_cast<uint16_t>(slot_index));
} else {
UNIMPLEMENTED();
@@ -490,18 +466,16 @@
return *this;
}
-
BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty(
- Register object, const Handle<String> name, int feedback_slot,
- LanguageMode language_mode) {
- Bytecode bytecode = BytecodeForLoadIC(language_mode);
+ Register object, const Handle<Name> name, int feedback_slot) {
size_t name_index = GetConstantPoolEntry(name);
if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) {
- Output(bytecode, object.ToOperand(), static_cast<uint8_t>(name_index),
+ 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(BytecodeForWideOperands(bytecode), object.ToOperand(),
+ Output(Bytecode::kLoadICWide, object.ToRawOperand(),
static_cast<uint16_t>(name_index),
static_cast<uint16_t>(feedback_slot));
} else {
@@ -510,14 +484,13 @@
return *this;
}
-
BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty(
- Register object, int feedback_slot, LanguageMode language_mode) {
- Bytecode bytecode = BytecodeForKeyedLoadIC(language_mode);
+ Register object, int feedback_slot) {
if (FitsInIdx8Operand(feedback_slot)) {
- Output(bytecode, object.ToOperand(), static_cast<uint8_t>(feedback_slot));
+ Output(Bytecode::kKeyedLoadIC, object.ToRawOperand(),
+ static_cast<uint8_t>(feedback_slot));
} else if (FitsInIdx16Operand(feedback_slot)) {
- Output(BytecodeForWideOperands(bytecode), object.ToOperand(),
+ Output(Bytecode::kKeyedLoadICWide, object.ToRawOperand(),
static_cast<uint16_t>(feedback_slot));
} else {
UNIMPLEMENTED();
@@ -525,18 +498,17 @@
return *this;
}
-
BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty(
- Register object, const Handle<String> name, int feedback_slot,
+ Register object, const Handle<Name> name, int feedback_slot,
LanguageMode language_mode) {
Bytecode bytecode = BytecodeForStoreIC(language_mode);
size_t name_index = GetConstantPoolEntry(name);
if (FitsInIdx8Operand(name_index) && FitsInIdx8Operand(feedback_slot)) {
- Output(bytecode, object.ToOperand(), static_cast<uint8_t>(name_index),
+ 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.ToOperand(),
+ Output(BytecodeForWideOperands(bytecode), object.ToRawOperand(),
static_cast<uint16_t>(name_index),
static_cast<uint16_t>(feedback_slot));
} else {
@@ -551,11 +523,11 @@
LanguageMode language_mode) {
Bytecode bytecode = BytecodeForKeyedStoreIC(language_mode);
if (FitsInIdx8Operand(feedback_slot)) {
- Output(bytecode, object.ToOperand(), key.ToOperand(),
+ Output(bytecode, object.ToRawOperand(), key.ToRawOperand(),
static_cast<uint8_t>(feedback_slot));
} else if (FitsInIdx16Operand(feedback_slot)) {
- Output(BytecodeForWideOperands(bytecode), object.ToOperand(),
- key.ToOperand(), static_cast<uint16_t>(feedback_slot));
+ Output(BytecodeForWideOperands(bytecode), object.ToRawOperand(),
+ key.ToRawOperand(), static_cast<uint16_t>(feedback_slot));
} else {
UNIMPLEMENTED();
}
@@ -653,13 +625,13 @@
BytecodeArrayBuilder& BytecodeArrayBuilder::PushContext(Register context) {
- Output(Bytecode::kPushContext, context.ToOperand());
+ Output(Bytecode::kPushContext, context.ToRawOperand());
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) {
- Output(Bytecode::kPopContext, context.ToOperand());
+ Output(Bytecode::kPopContext, context.ToRawOperand());
return *this;
}
@@ -766,6 +738,8 @@
return Bytecode::kJumpIfToBooleanTrueConstant;
case Bytecode::kJumpIfToBooleanFalse:
return Bytecode::kJumpIfToBooleanFalseConstant;
+ case Bytecode::kJumpIfNotHole:
+ return Bytecode::kJumpIfNotHoleConstant;
case Bytecode::kJumpIfNull:
return Bytecode::kJumpIfNullConstant;
case Bytecode::kJumpIfUndefined:
@@ -791,6 +765,8 @@
return Bytecode::kJumpIfToBooleanTrueConstantWide;
case Bytecode::kJumpIfToBooleanFalse:
return Bytecode::kJumpIfToBooleanFalseConstantWide;
+ case Bytecode::kJumpIfNotHole:
+ return Bytecode::kJumpIfNotHoleConstantWide;
case Bytecode::kJumpIfNull:
return Bytecode::kJumpIfNullConstantWide;
case Bytecode::kJumpIfUndefined:
@@ -808,6 +784,7 @@
case Bytecode::kJump:
case Bytecode::kJumpIfNull:
case Bytecode::kJumpIfUndefined:
+ case Bytecode::kJumpIfNotHole:
return jump_bytecode;
case Bytecode::kJumpIfTrue:
return Bytecode::kJumpIfToBooleanTrue;
@@ -883,7 +860,10 @@
BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode,
BytecodeLabel* label) {
// Don't emit dead code.
- if (exit_seen_in_block_) return *this;
+ if (exit_seen_in_block_) {
+ source_position_table_builder_.RevertPosition(bytecodes()->size());
+ return *this;
+ }
// Check if the value in accumulator is boolean, if not choose an
// appropriate JumpIfToBoolean bytecode.
@@ -965,6 +945,15 @@
return OutputJump(Bytecode::kJumpIfUndefined, label);
}
+BytecodeArrayBuilder& BytecodeArrayBuilder::StackCheck() {
+ Output(Bytecode::kStackCheck);
+ return *this;
+}
+
+BytecodeArrayBuilder& BytecodeArrayBuilder::JumpIfNotHole(
+ BytecodeLabel* label) {
+ return OutputJump(Bytecode::kJumpIfNotHole, label);
+}
BytecodeArrayBuilder& BytecodeArrayBuilder::Throw() {
Output(Bytecode::kThrow);
@@ -973,40 +962,86 @@
}
+BytecodeArrayBuilder& BytecodeArrayBuilder::ReThrow() {
+ Output(Bytecode::kReThrow);
+ exit_seen_in_block_ = true;
+ return *this;
+}
+
+
BytecodeArrayBuilder& BytecodeArrayBuilder::Return() {
Output(Bytecode::kReturn);
exit_seen_in_block_ = true;
return *this;
}
+BytecodeArrayBuilder& BytecodeArrayBuilder::Debugger() {
+ Output(Bytecode::kDebugger);
+ return *this;
+}
BytecodeArrayBuilder& BytecodeArrayBuilder::ForInPrepare(
- Register cache_type, Register cache_array, Register cache_length) {
- Output(Bytecode::kForInPrepare, cache_type.ToOperand(),
- cache_array.ToOperand(), cache_length.ToOperand());
+ 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();
+ }
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::ForInDone(Register index,
Register cache_length) {
- Output(Bytecode::kForInDone, index.ToOperand(), cache_length.ToOperand());
+ Output(Bytecode::kForInDone, index.ToRawOperand(),
+ cache_length.ToRawOperand());
return *this;
}
-BytecodeArrayBuilder& BytecodeArrayBuilder::ForInNext(Register receiver,
- Register cache_type,
- Register cache_array,
- Register index) {
- Output(Bytecode::kForInNext, receiver.ToOperand(), cache_type.ToOperand(),
- cache_array.ToOperand(), index.ToOperand());
+BytecodeArrayBuilder& BytecodeArrayBuilder::ForInNext(
+ Register receiver, Register index, Register cache_type_array_pair) {
+ if (FitsInReg8Operand(receiver) && FitsInReg8Operand(index) &&
+ FitsInReg8Operand(cache_type_array_pair)) {
+ Output(Bytecode::kForInNext, receiver.ToRawOperand(), index.ToRawOperand(),
+ cache_type_array_pair.ToRawOperand());
+ } else if (FitsInReg16Operand(receiver) && FitsInReg16Operand(index) &&
+ FitsInReg16Operand(cache_type_array_pair)) {
+ Output(Bytecode::kForInNextWide, receiver.ToRawOperand(),
+ index.ToRawOperand(), cache_type_array_pair.ToRawOperand());
+ } else {
+ UNIMPLEMENTED();
+ }
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::ForInStep(Register index) {
- Output(Bytecode::kForInStep, index.ToOperand());
+ Output(Bytecode::kForInStep, index.ToRawOperand());
+ return *this;
+}
+
+
+BytecodeArrayBuilder& BytecodeArrayBuilder::MarkHandler(int handler_id,
+ bool will_catch) {
+ handler_table_builder()->SetHandlerTarget(handler_id, bytecodes()->size());
+ handler_table_builder()->SetPrediction(handler_id, will_catch);
+ return *this;
+}
+
+
+BytecodeArrayBuilder& BytecodeArrayBuilder::MarkTryBegin(int handler_id,
+ Register context) {
+ handler_table_builder()->SetTryRegionStart(handler_id, bytecodes()->size());
+ handler_table_builder()->SetContextRegister(handler_id, context);
+ return *this;
+}
+
+
+BytecodeArrayBuilder& BytecodeArrayBuilder::MarkTryEnd(int handler_id) {
+ handler_table_builder()->SetTryRegionEnd(handler_id, bytecodes()->size());
return *this;
}
@@ -1016,27 +1051,33 @@
exit_seen_in_block_ = false;
}
-
-void BytecodeArrayBuilder::EnsureReturn() {
+void BytecodeArrayBuilder::EnsureReturn(FunctionLiteral* literal) {
if (!exit_seen_in_block_) {
LoadUndefined();
+ SetReturnPosition(literal);
Return();
}
}
-
BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable,
- Register receiver,
- size_t arg_count,
- int feedback_slot) {
- if (FitsInIdx8Operand(arg_count) && FitsInIdx8Operand(feedback_slot)) {
- Output(Bytecode::kCall, callable.ToOperand(), receiver.ToOperand(),
- static_cast<uint8_t>(arg_count),
+ Register receiver_args,
+ size_t receiver_args_count,
+ 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 (FitsInIdx16Operand(arg_count) &&
+ } else if (FitsInReg16Operand(callable) &&
+ FitsInReg16Operand(receiver_args) &&
+ FitsInIdx16Operand(receiver_args_count) &&
FitsInIdx16Operand(feedback_slot)) {
- Output(Bytecode::kCallWide, callable.ToOperand(), receiver.ToOperand(),
- static_cast<uint16_t>(arg_count),
+ 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();
@@ -1044,7 +1085,6 @@
return *this;
}
-
BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor,
Register first_arg,
size_t arg_count) {
@@ -1052,9 +1092,17 @@
DCHECK_EQ(0u, arg_count);
first_arg = Register(0);
}
- DCHECK(FitsInIdx8Operand(arg_count));
- Output(Bytecode::kNew, constructor.ToOperand(), first_arg.ToOperand(),
- static_cast<uint8_t>(arg_count));
+ 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();
+ }
return *this;
}
@@ -1063,13 +1111,19 @@
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(FitsInIdx8Operand(arg_count));
if (!first_arg.is_valid()) {
DCHECK_EQ(0u, arg_count);
first_arg = Register(0);
}
- Output(Bytecode::kCallRuntime, static_cast<uint16_t>(function_id),
- first_arg.ToOperand(), static_cast<uint8_t>(arg_count));
+ 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();
+ }
return *this;
}
@@ -1079,38 +1133,49 @@
Register first_return) {
DCHECK_EQ(2, Runtime::FunctionForId(function_id)->result_size);
DCHECK(FitsInIdx16Operand(function_id));
- DCHECK(FitsInIdx8Operand(arg_count));
if (!first_arg.is_valid()) {
DCHECK_EQ(0u, arg_count);
first_arg = Register(0);
}
- Output(Bytecode::kCallRuntimeForPair, static_cast<uint16_t>(function_id),
- first_arg.ToOperand(), static_cast<uint8_t>(arg_count),
- first_return.ToOperand());
+ 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();
+ }
return *this;
}
-
-BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime(int context_index,
- Register receiver,
- size_t arg_count) {
+BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime(
+ int context_index, Register receiver_args, size_t receiver_args_count) {
DCHECK(FitsInIdx16Operand(context_index));
- DCHECK(FitsInIdx8Operand(arg_count));
- Output(Bytecode::kCallJSRuntime, static_cast<uint16_t>(context_index),
- receiver.ToOperand(), static_cast<uint8_t>(arg_count));
+ 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();
+ }
return *this;
}
BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object,
LanguageMode language_mode) {
- Output(BytecodeForDelete(language_mode), object.ToOperand());
- return *this;
-}
-
-
-BytecodeArrayBuilder& BytecodeArrayBuilder::DeleteLookupSlot() {
- Output(Bytecode::kDeleteLookupSlot);
+ Output(BytecodeForDelete(language_mode), object.ToRawOperand());
return *this;
}
@@ -1119,126 +1184,62 @@
return constant_array_builder()->Insert(object);
}
-
-int BytecodeArrayBuilder::BorrowTemporaryRegister() {
- if (free_temporaries_.empty()) {
- temporary_register_count_ += 1;
- return last_temporary_register().index();
- } else {
- auto pos = free_temporaries_.begin();
- int retval = *pos;
- free_temporaries_.erase(pos);
- return retval;
- }
+void BytecodeArrayBuilder::SetReturnPosition(FunctionLiteral* fun) {
+ int pos = std::max(fun->start_position(), fun->end_position() - 1);
+ source_position_table_builder_.AddStatementPosition(bytecodes_.size(), pos);
}
-
-int BytecodeArrayBuilder::BorrowTemporaryRegisterNotInRange(int start_index,
- int end_index) {
- auto index = free_temporaries_.lower_bound(start_index);
- if (index == free_temporaries_.begin()) {
- // If start_index is the first free register, check for a register
- // greater than end_index.
- index = free_temporaries_.upper_bound(end_index);
- if (index == free_temporaries_.end()) {
- temporary_register_count_ += 1;
- return last_temporary_register().index();
- }
- } else {
- // If there is a free register < start_index
- index--;
- }
-
- int retval = *index;
- free_temporaries_.erase(index);
- return retval;
+void BytecodeArrayBuilder::SetStatementPosition(Statement* stmt) {
+ if (stmt->position() == RelocInfo::kNoPosition) return;
+ source_position_table_builder_.AddStatementPosition(bytecodes_.size(),
+ stmt->position());
}
-
-void BytecodeArrayBuilder::BorrowConsecutiveTemporaryRegister(int reg_index) {
- DCHECK(free_temporaries_.find(reg_index) != free_temporaries_.end());
- free_temporaries_.erase(reg_index);
+void BytecodeArrayBuilder::SetExpressionPosition(Expression* expr) {
+ if (expr->position() == RelocInfo::kNoPosition) return;
+ source_position_table_builder_.AddExpressionPosition(bytecodes_.size(),
+ expr->position());
}
-
-void BytecodeArrayBuilder::ReturnTemporaryRegister(int reg_index) {
- DCHECK(free_temporaries_.find(reg_index) == free_temporaries_.end());
- free_temporaries_.insert(reg_index);
-}
-
-
-int BytecodeArrayBuilder::PrepareForConsecutiveTemporaryRegisters(
- size_t count) {
- if (count == 0) {
- return -1;
- }
-
- // 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)) {
- start = run_end;
- run_length = 0;
- }
- if (++run_length == count) {
- return *start;
- }
- }
-
- // Continue run if possible across existing last temporary.
- if (temporary_register_count_ > 0 &&
- (start == free_temporaries_.end() ||
- *start + static_cast<int>(run_length) !=
- last_temporary_register().index() + 1)) {
- run_length = 0;
- }
-
- // Ensure enough registers for run.
- while (run_length++ < count) {
- temporary_register_count_++;
- free_temporaries_.insert(last_temporary_register().index());
- }
- return last_temporary_register().index() - static_cast<int>(count) + 1;
-}
-
-
bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const {
- if (temporary_register_count_ > 0) {
- DCHECK(reg.index() >= first_temporary_register().index() &&
- reg.index() <= last_temporary_register().index());
- return free_temporaries_.find(reg.index()) == free_temporaries_.end();
- } else {
- return false;
- }
+ return temporary_register_allocator()->RegisterIsLive(reg);
}
-
-bool BytecodeArrayBuilder::RegisterIsValid(Register reg) const {
- if (reg.is_function_context() || reg.is_function_closure() ||
- reg.is_new_target()) {
- return true;
- } 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 {
- return TemporaryRegisterIsLive(reg);
- }
-}
-
-
bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode, int operand_index,
uint32_t operand_value) const {
OperandType operand_type = Bytecodes::GetOperandType(bytecode, operand_index);
switch (operand_type) {
case OperandType::kNone:
return false;
- case OperandType::kCount16:
+ 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.
+ 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;
+ }
+ }
case OperandType::kIdx16:
return static_cast<uint16_t>(operand_value) == operand_value;
- case OperandType::kCount8:
case OperandType::kImm8:
case OperandType::kIdx8:
return static_cast<uint8_t>(operand_value) == operand_value;
@@ -1248,27 +1249,84 @@
}
// Fall-through to kReg8 case.
case OperandType::kReg8:
- return RegisterIsValid(
- Register::FromOperand(static_cast<uint8_t>(operand_value)));
- case OperandType::kRegPair8: {
- Register reg0 =
- Register::FromOperand(static_cast<uint8_t>(operand_value));
+ case OperandType::kRegOut8:
+ return RegisterIsValid(Register::FromRawOperand(operand_value),
+ operand_type);
+ case OperandType::kRegOutPair8:
+ case OperandType::kRegOutPair16:
+ case OperandType::kRegPair8:
+ case OperandType::kRegPair16: {
+ Register reg0 = Register::FromRawOperand(operand_value);
Register reg1 = Register(reg0.index() + 1);
- return RegisterIsValid(reg0) && RegisterIsValid(reg1);
+ return RegisterIsValid(reg0, operand_type) &&
+ RegisterIsValid(reg1, operand_type);
}
- case OperandType::kReg16:
- if (bytecode != Bytecode::kExchange &&
- bytecode != Bytecode::kExchangeWide) {
- return false;
+ case OperandType::kRegOutTriple8:
+ case OperandType::kRegOutTriple16: {
+ 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;
}
- return RegisterIsValid(
- Register::FromWideOperand(static_cast<uint16_t>(operand_value)));
+ // Fall-through to kReg16 case.
+ case OperandType::kReg16:
+ case OperandType::kRegOut16: {
+ Register reg = Register::FromRawOperand(operand_value);
+ return RegisterIsValid(reg, operand_type);
+ }
}
UNREACHABLE();
return false;
}
+bool BytecodeArrayBuilder::RegisterIsValid(Register reg,
+ OperandType reg_type) 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 (reg.is_current_context() || reg.is_function_closure() ||
+ reg.is_new_target()) {
+ return true;
+ } 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 {
+ reg = RegisterTranslator::UntranslateRegister(reg);
+ if (reg.index() < fixed_register_count()) {
+ return true;
+ } else {
+ return TemporaryRegisterIsLive(reg);
+ }
+ }
+}
+
+
bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const {
return last_bytecode_start_ < bytecodes()->size() &&
last_bytecode_start_ >= last_block_end_;
@@ -1279,9 +1337,10 @@
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_reg =
+ Register::FromOperand(previous_bytecode.GetOperand(0));
+ return previous_reg == reg;
}
}
return false;
@@ -1367,14 +1426,14 @@
// static
Bytecode BytecodeArrayBuilder::BytecodeForWideOperands(Bytecode bytecode) {
switch (bytecode) {
- case Bytecode::kLoadICSloppy:
- return Bytecode::kLoadICSloppyWide;
- case Bytecode::kLoadICStrict:
- return Bytecode::kLoadICStrictWide;
- case Bytecode::kKeyedLoadICSloppy:
- return Bytecode::kKeyedLoadICSloppyWide;
- case Bytecode::kKeyedLoadICStrict:
- return Bytecode::kKeyedLoadICStrictWide;
+ 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:
@@ -1383,14 +1442,10 @@
return Bytecode::kKeyedStoreICSloppyWide;
case Bytecode::kKeyedStoreICStrict:
return Bytecode::kKeyedStoreICStrictWide;
- case Bytecode::kLdaGlobalSloppy:
- return Bytecode::kLdaGlobalSloppyWide;
- case Bytecode::kLdaGlobalStrict:
- return Bytecode::kLdaGlobalStrictWide;
- case Bytecode::kLdaGlobalInsideTypeofSloppy:
- return Bytecode::kLdaGlobalInsideTypeofSloppyWide;
- case Bytecode::kLdaGlobalInsideTypeofStrict:
- return Bytecode::kLdaGlobalInsideTypeofStrictWide;
+ case Bytecode::kLdaGlobal:
+ return Bytecode::kLdaGlobalWide;
+ case Bytecode::kLdaGlobalInsideTypeof:
+ return Bytecode::kLdaGlobalInsideTypeofWide;
case Bytecode::kStaGlobalSloppy:
return Bytecode::kStaGlobalSloppyWide;
case Bytecode::kStaGlobalStrict:
@@ -1411,39 +1466,6 @@
// static
-Bytecode BytecodeArrayBuilder::BytecodeForLoadIC(LanguageMode language_mode) {
- switch (language_mode) {
- case SLOPPY:
- return Bytecode::kLoadICSloppy;
- case STRICT:
- return Bytecode::kLoadICStrict;
- case STRONG:
- UNIMPLEMENTED();
- default:
- UNREACHABLE();
- }
- return static_cast<Bytecode>(-1);
-}
-
-
-// static
-Bytecode BytecodeArrayBuilder::BytecodeForKeyedLoadIC(
- LanguageMode language_mode) {
- switch (language_mode) {
- case SLOPPY:
- return Bytecode::kKeyedLoadICSloppy;
- case STRICT:
- return Bytecode::kKeyedLoadICStrict;
- case STRONG:
- UNIMPLEMENTED();
- default:
- UNREACHABLE();
- }
- return static_cast<Bytecode>(-1);
-}
-
-
-// static
Bytecode BytecodeArrayBuilder::BytecodeForStoreIC(LanguageMode language_mode) {
switch (language_mode) {
case SLOPPY:
@@ -1477,23 +1499,9 @@
// static
-Bytecode BytecodeArrayBuilder::BytecodeForLoadGlobal(LanguageMode language_mode,
- TypeofMode typeof_mode) {
- switch (language_mode) {
- case SLOPPY:
- return typeof_mode == INSIDE_TYPEOF
- ? Bytecode::kLdaGlobalInsideTypeofSloppy
- : Bytecode::kLdaGlobalSloppy;
- case STRICT:
- return typeof_mode == INSIDE_TYPEOF
- ? Bytecode::kLdaGlobalInsideTypeofStrict
- : Bytecode::kLdaGlobalStrict;
- case STRONG:
- UNIMPLEMENTED();
- default:
- UNREACHABLE();
- }
- return static_cast<Bytecode>(-1);
+Bytecode BytecodeArrayBuilder::BytecodeForLoadGlobal(TypeofMode typeof_mode) {
+ return typeof_mode == INSIDE_TYPEOF ? Bytecode::kLdaGlobalInsideTypeof
+ : Bytecode::kLdaGlobal;
}
@@ -1530,7 +1538,6 @@
return static_cast<Bytecode>(-1);
}
-
// static
Bytecode BytecodeArrayBuilder::BytecodeForCreateArguments(
CreateArgumentsType type) {
@@ -1539,9 +1546,10 @@
return Bytecode::kCreateMappedArguments;
case CreateArgumentsType::kUnmappedArguments:
return Bytecode::kCreateUnmappedArguments;
- default:
- UNREACHABLE();
+ case CreateArgumentsType::kRestParameter:
+ return Bytecode::kCreateRestParameter;
}
+ UNREACHABLE();
return static_cast<Bytecode>(-1);
}
@@ -1561,6 +1569,18 @@
return static_cast<Bytecode>(-1);
}
+// static
+Bytecode BytecodeArrayBuilder::BytecodeForCall(TailCallMode tail_call_mode) {
+ switch (tail_call_mode) {
+ case TailCallMode::kDisallow:
+ return Bytecode::kCall;
+ case TailCallMode::kAllow:
+ return Bytecode::kTailCall;
+ default:
+ UNREACHABLE();
+ }
+ return static_cast<Bytecode>(-1);
+}
// static
bool BytecodeArrayBuilder::FitsInIdx8Operand(int value) {
@@ -1594,13 +1614,23 @@
// 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