| Index: src/interpreter/bytecode-array-builder.cc
|
| diff --git a/src/interpreter/bytecode-array-builder.cc b/src/interpreter/bytecode-array-builder.cc
|
| index 20419043a54a942432dc97928ba739271be4530a..4205f6aaa96e52968cf0b68fe681eb8c1db1ea96 100644
|
| --- a/src/interpreter/bytecode-array-builder.cc
|
| +++ b/src/interpreter/bytecode-array-builder.cc
|
| @@ -3,117 +3,44 @@
|
| // found in the LICENSE file.
|
|
|
| #include "src/interpreter/bytecode-array-builder.h"
|
| +
|
| #include "src/compiler.h"
|
| +#include "src/interpreter/bytecode-peephole-optimizer.h"
|
| #include "src/interpreter/interpreter-intrinsics.h"
|
|
|
| namespace v8 {
|
| namespace internal {
|
| namespace interpreter {
|
|
|
| -class BytecodeArrayBuilder::PreviousBytecodeHelper BASE_EMBEDDED {
|
| - public:
|
| - explicit PreviousBytecodeHelper(const BytecodeArrayBuilder& array_builder)
|
| - : array_builder_(array_builder),
|
| - previous_bytecode_start_(array_builder_.last_bytecode_start_) {
|
| - // This helper is expected to be instantiated only when the last bytecode is
|
| - // in the same basic block.
|
| - DCHECK(array_builder_.LastBytecodeInSameBlock());
|
| - bytecode_ = Bytecodes::FromByte(
|
| - array_builder_.bytecodes()->at(previous_bytecode_start_));
|
| - operand_scale_ = OperandScale::kSingle;
|
| - if (Bytecodes::IsPrefixScalingBytecode(bytecode_)) {
|
| - operand_scale_ = Bytecodes::PrefixBytecodeToOperandScale(bytecode_);
|
| - bytecode_ = Bytecodes::FromByte(
|
| - array_builder_.bytecodes()->at(previous_bytecode_start_ + 1));
|
| - }
|
| - }
|
| -
|
| - // Returns the previous bytecode in the same basic block.
|
| - MUST_USE_RESULT Bytecode GetBytecode() const {
|
| - DCHECK_EQ(array_builder_.last_bytecode_start_, previous_bytecode_start_);
|
| - return bytecode_;
|
| - }
|
| -
|
| - MUST_USE_RESULT Register GetRegisterOperand(int operand_index) const {
|
| - return Register::FromOperand(GetSignedOperand(operand_index));
|
| - }
|
| -
|
| - MUST_USE_RESULT uint32_t GetIndexOperand(int operand_index) const {
|
| - return GetUnsignedOperand(operand_index);
|
| - }
|
| -
|
| - Handle<Object> GetConstantForIndexOperand(int operand_index) const {
|
| - return array_builder_.constant_array_builder()->At(
|
| - GetIndexOperand(operand_index));
|
| - }
|
| -
|
| - private:
|
| - // Returns the signed operand at operand_index for the previous
|
| - // bytecode in the same basic block.
|
| - MUST_USE_RESULT int32_t GetSignedOperand(int operand_index) const {
|
| - DCHECK_EQ(array_builder_.last_bytecode_start_, previous_bytecode_start_);
|
| - OperandType operand_type =
|
| - Bytecodes::GetOperandType(bytecode_, operand_index);
|
| - DCHECK(!Bytecodes::IsUnsignedOperandType(operand_type));
|
| - const uint8_t* operand_start = GetOperandStart(operand_index);
|
| - return Bytecodes::DecodeSignedOperand(operand_start, operand_type,
|
| - operand_scale_);
|
| - }
|
| -
|
| - // Returns the unsigned operand at operand_index for the previous
|
| - // bytecode in the same basic block.
|
| - MUST_USE_RESULT uint32_t GetUnsignedOperand(int operand_index) const {
|
| - DCHECK_EQ(array_builder_.last_bytecode_start_, previous_bytecode_start_);
|
| - OperandType operand_type =
|
| - Bytecodes::GetOperandType(bytecode_, operand_index);
|
| - DCHECK(Bytecodes::IsUnsignedOperandType(operand_type));
|
| - const uint8_t* operand_start = GetOperandStart(operand_index);
|
| - return Bytecodes::DecodeUnsignedOperand(operand_start, operand_type,
|
| - operand_scale_);
|
| - }
|
| -
|
| - const uint8_t* GetOperandStart(int operand_index) const {
|
| - size_t operand_offset =
|
| - previous_bytecode_start_ + prefix_offset() +
|
| - Bytecodes::GetOperandOffset(bytecode_, operand_index, operand_scale_);
|
| - return &(*array_builder_.bytecodes())[0] + operand_offset;
|
| - }
|
| -
|
| - int prefix_offset() const {
|
| - return Bytecodes::OperandScaleRequiresPrefixBytecode(operand_scale_) ? 1
|
| - : 0;
|
| - }
|
| -
|
| - const BytecodeArrayBuilder& array_builder_;
|
| - OperandScale operand_scale_;
|
| - Bytecode bytecode_;
|
| - size_t previous_bytecode_start_;
|
| -
|
| - DISALLOW_COPY_AND_ASSIGN(PreviousBytecodeHelper);
|
| -};
|
| -
|
| BytecodeArrayBuilder::BytecodeArrayBuilder(Isolate* isolate, Zone* zone,
|
| int parameter_count,
|
| int context_count, int locals_count,
|
| FunctionLiteral* literal)
|
| : 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_(parameter_count),
|
| local_register_count_(locals_count),
|
| context_register_count_(context_count),
|
| - temporary_allocator_(zone, fixed_register_count()) {
|
| + temporary_allocator_(zone, fixed_register_count()),
|
| + bytecode_node_allocator_(zone),
|
| + final_stage_writer_(zone, &source_position_table_builder_),
|
| + writer_(&final_stage_writer_) {
|
| + current_node_ = bytecode_node_allocator()->Allocate();
|
| DCHECK_GE(parameter_count_, 0);
|
| DCHECK_GE(context_register_count_, 0);
|
| DCHECK_GE(local_register_count_, 0);
|
| +
|
| + if (FLAG_ignition_peephole) {
|
| + writer_ =
|
| + new (zone) BytecodePeepholeOptimizer(&constant_array_builder_, writer_);
|
| + }
|
| +
|
| return_position_ =
|
| literal ? std::max(literal->start_position(), literal->end_position() - 1)
|
| : RelocInfo::kNoPosition;
|
| @@ -149,15 +76,22 @@ Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() {
|
| DCHECK_EQ(bytecode_generated_, false);
|
| DCHECK(exit_seen_in_block_);
|
|
|
| - int bytecode_size = static_cast<int>(bytecodes_.size());
|
| - int register_count = fixed_and_temporary_register_count();
|
| - int frame_size = register_count * kPointerSize;
|
| + writer()->LeaveBasicBlock();
|
| + const ZoneVector<uint8_t>* bytecodes = final_stage_writer()->bytecodes();
|
| +
|
| + int bytecode_size = static_cast<int>(bytecodes->size());
|
| +
|
| + // All locals need a frame slot for the debugger, but may not be
|
| + // present in generated code.
|
| + int frame_size_for_locals = fixed_register_count() * kPointerSize;
|
| + int frame_size_measured = final_stage_writer()->GetMeasuredFrameSize();
|
| + int frame_size = std::max(frame_size_for_locals, frame_size_measured);
|
| Handle<FixedArray> constant_pool = constant_array_builder()->ToFixedArray();
|
| Handle<FixedArray> handler_table = handler_table_builder()->ToHandlerTable();
|
| Handle<ByteArray> source_position_table =
|
| source_position_table_builder()->ToSourcePositionTable();
|
| Handle<BytecodeArray> bytecode_array = isolate_->factory()->NewBytecodeArray(
|
| - bytecode_size, &bytecodes_.front(), frame_size, parameter_count(),
|
| + bytecode_size, &bytecodes->front(), frame_size, parameter_count(),
|
| constant_pool);
|
| bytecode_array->set_handler_table(*handler_table);
|
| bytecode_array->set_source_position_table(*source_position_table);
|
| @@ -170,95 +104,73 @@ Handle<BytecodeArray> BytecodeArrayBuilder::ToBytecodeArray() {
|
| return bytecode_array;
|
| }
|
|
|
| -template <size_t N>
|
| -void BytecodeArrayBuilder::Output(Bytecode bytecode, uint32_t (&operands)[N],
|
| - OperandScale 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);
|
| -
|
| - last_bytecode_start_ = bytecodes()->size();
|
| - // Emit prefix bytecode for scale if required.
|
| - if (Bytecodes::OperandScaleRequiresPrefixBytecode(operand_scale)) {
|
| - bytecodes()->push_back(Bytecodes::ToByte(
|
| - Bytecodes::OperandScaleToPrefixBytecode(operand_scale)));
|
| - }
|
| -
|
| - // Emit bytecode.
|
| - bytecodes()->push_back(Bytecodes::ToByte(bytecode));
|
| -
|
| - // Emit operands.
|
| - for (int i = 0; i < operand_count; i++) {
|
| - DCHECK(OperandIsValid(bytecode, operand_scale, i, operands[i]));
|
| - switch (Bytecodes::GetOperandSize(bytecode, i, operand_scale)) {
|
| - case OperandSize::kNone:
|
| - UNREACHABLE();
|
| - break;
|
| - case OperandSize::kByte:
|
| - bytecodes()->push_back(static_cast<uint8_t>(operands[i]));
|
| - break;
|
| - case OperandSize::kShort: {
|
| - uint8_t operand_bytes[2];
|
| - WriteUnalignedUInt16(operand_bytes, operands[i]);
|
| - bytecodes()->insert(bytecodes()->end(), operand_bytes,
|
| - 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;
|
| - }
|
| - }
|
| - }
|
| -}
|
| -
|
| 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));
|
| + current_node_->set_bytecode(bytecode);
|
| + writer()->Write(current_node_);
|
| + current_node_ = bytecode_node_allocator()->Allocate();
|
| }
|
|
|
| void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode,
|
| OperandScale 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);
|
| + // Don't output dead code.
|
| + if (exit_seen_in_block_) return;
|
| + DCHECK(OperandIsValid(bytecode, operand_scale, 0, operand0));
|
| + DCHECK(OperandIsValid(bytecode, operand_scale, 1, operand1));
|
| + DCHECK(OperandIsValid(bytecode, operand_scale, 2, operand2));
|
| + DCHECK(OperandIsValid(bytecode, operand_scale, 3, operand3));
|
| + current_node_->set_bytecode(bytecode, operand0, operand1, operand2, operand3,
|
| + operand_scale);
|
| + writer()->Write(current_node_);
|
| + current_node_ = bytecode_node_allocator()->Allocate();
|
| }
|
|
|
| void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode,
|
| OperandScale operand_scale,
|
| uint32_t operand0, uint32_t operand1,
|
| uint32_t operand2) {
|
| - uint32_t operands[] = {operand0, operand1, operand2};
|
| - Output(bytecode, operands, operand_scale);
|
| + // Don't output dead code.
|
| + if (exit_seen_in_block_) return;
|
| + DCHECK(OperandIsValid(bytecode, operand_scale, 0, operand0));
|
| + DCHECK(OperandIsValid(bytecode, operand_scale, 1, operand1));
|
| + DCHECK(OperandIsValid(bytecode, operand_scale, 2, operand2));
|
| + current_node_->set_bytecode(bytecode, operand0, operand1, operand2,
|
| + operand_scale);
|
| + writer()->Write(current_node_);
|
| + current_node_ = bytecode_node_allocator()->Allocate();
|
| }
|
|
|
| void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode,
|
| OperandScale operand_scale,
|
| uint32_t operand0, uint32_t operand1) {
|
| - uint32_t operands[] = {operand0, operand1};
|
| - Output(bytecode, operands, operand_scale);
|
| + // Don't output dead code.
|
| + if (exit_seen_in_block_) return;
|
| + DCHECK(OperandIsValid(bytecode, operand_scale, 0, operand0));
|
| + DCHECK(OperandIsValid(bytecode, operand_scale, 1, operand1));
|
| + current_node_->set_bytecode(bytecode, operand0, operand1, operand_scale);
|
| + writer()->Write(current_node_);
|
| + current_node_ = bytecode_node_allocator()->Allocate();
|
| }
|
|
|
| void BytecodeArrayBuilder::OutputScaled(Bytecode bytecode,
|
| OperandScale operand_scale,
|
| uint32_t operand0) {
|
| - uint32_t operands[] = {operand0};
|
| - Output(bytecode, operands, operand_scale);
|
| + // Don't output dead code.
|
| + if (exit_seen_in_block_) return;
|
| + DCHECK(OperandIsValid(bytecode, operand_scale, 0, operand0));
|
| + current_node_->set_bytecode(bytecode, operand0, operand_scale);
|
| + writer()->Write(current_node_);
|
| + current_node_ = bytecode_node_allocator()->Allocate();
|
| }
|
|
|
| BytecodeArrayBuilder& BytecodeArrayBuilder::BinaryOperation(Token::Value op,
|
| Register reg) {
|
| - OperandScale operand_scale = OperandSizesToScale(reg.SizeOfOperand());
|
| + OperandScale operand_scale =
|
| + Bytecodes::OperandSizesToScale(reg.SizeOfOperand());
|
| OutputScaled(BytecodeForBinaryOperation(op), operand_scale,
|
| RegisterOperand(reg));
|
| return *this;
|
| @@ -283,7 +195,8 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::TypeOf() {
|
|
|
| BytecodeArrayBuilder& BytecodeArrayBuilder::CompareOperation(Token::Value op,
|
| Register reg) {
|
| - OperandScale operand_scale = OperandSizesToScale(reg.SizeOfOperand());
|
| + OperandScale operand_scale =
|
| + Bytecodes::OperandSizesToScale(reg.SizeOfOperand());
|
| OutputScaled(BytecodeForCompareOperation(op), operand_scale,
|
| RegisterOperand(reg));
|
| return *this;
|
| @@ -296,8 +209,8 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(
|
| if (raw_smi == 0) {
|
| Output(Bytecode::kLdaZero);
|
| } else {
|
| - OperandSize operand_size = SizeForSignedOperand(raw_smi);
|
| - OperandScale operand_scale = OperandSizesToScale(operand_size);
|
| + OperandSize operand_size = Bytecodes::SizeForSignedOperand(raw_smi);
|
| + OperandScale operand_scale = Bytecodes::OperandSizesToScale(operand_size);
|
| OutputScaled(Bytecode::kLdaSmi, operand_scale,
|
| SignedOperand(raw_smi, operand_size));
|
| }
|
| @@ -308,7 +221,7 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(
|
| BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLiteral(Handle<Object> object) {
|
| size_t entry = GetConstantPoolEntry(object);
|
| OperandScale operand_scale =
|
| - OperandSizesToScale(SizeForUnsignedOperand(entry));
|
| + Bytecodes::OperandSizesToScale(Bytecodes::SizeForUnsignedOperand(entry));
|
| OutputScaled(Bytecode::kLdaConstant, operand_scale, UnsignedOperand(entry));
|
| return *this;
|
| }
|
| @@ -345,20 +258,18 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadFalse() {
|
|
|
| BytecodeArrayBuilder& BytecodeArrayBuilder::LoadAccumulatorWithRegister(
|
| Register reg) {
|
| - if (!IsRegisterInAccumulator(reg)) {
|
| - OperandScale operand_scale = OperandSizesToScale(reg.SizeOfOperand());
|
| - OutputScaled(Bytecode::kLdar, operand_scale, RegisterOperand(reg));
|
| - }
|
| + OperandScale operand_scale =
|
| + Bytecodes::OperandSizesToScale(reg.SizeOfOperand());
|
| + OutputScaled(Bytecode::kLdar, operand_scale, RegisterOperand(reg));
|
| return *this;
|
| }
|
|
|
|
|
| BytecodeArrayBuilder& BytecodeArrayBuilder::StoreAccumulatorInRegister(
|
| Register reg) {
|
| - if (!IsRegisterInAccumulator(reg)) {
|
| - OperandScale operand_scale = OperandSizesToScale(reg.SizeOfOperand());
|
| - OutputScaled(Bytecode::kStar, operand_scale, RegisterOperand(reg));
|
| - }
|
| + OperandScale operand_scale =
|
| + Bytecodes::OperandSizesToScale(reg.SizeOfOperand());
|
| + OutputScaled(Bytecode::kStar, operand_scale, RegisterOperand(reg));
|
| return *this;
|
| }
|
|
|
| @@ -367,7 +278,7 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::MoveRegister(Register from,
|
| Register to) {
|
| DCHECK(from != to);
|
| OperandScale operand_scale =
|
| - OperandSizesToScale(from.SizeOfOperand(), to.SizeOfOperand());
|
| + Bytecodes::OperandSizesToScale(from.SizeOfOperand(), to.SizeOfOperand());
|
| OutputScaled(Bytecode::kMov, operand_scale, RegisterOperand(from),
|
| RegisterOperand(to));
|
| return *this;
|
| @@ -379,9 +290,9 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadGlobal(
|
| // operand rather than having extra bytecodes.
|
| Bytecode bytecode = BytecodeForLoadGlobal(typeof_mode);
|
| size_t name_index = GetConstantPoolEntry(name);
|
| - OperandScale operand_scale =
|
| - OperandSizesToScale(SizeForUnsignedOperand(name_index),
|
| - SizeForUnsignedOperand(feedback_slot));
|
| + OperandScale operand_scale = Bytecodes::OperandSizesToScale(
|
| + Bytecodes::SizeForUnsignedOperand(name_index),
|
| + Bytecodes::SizeForUnsignedOperand(feedback_slot));
|
| OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index),
|
| UnsignedOperand(feedback_slot));
|
| return *this;
|
| @@ -391,9 +302,9 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::StoreGlobal(
|
| const Handle<String> name, int feedback_slot, LanguageMode language_mode) {
|
| Bytecode bytecode = BytecodeForStoreGlobal(language_mode);
|
| size_t name_index = GetConstantPoolEntry(name);
|
| - OperandScale operand_scale =
|
| - OperandSizesToScale(SizeForUnsignedOperand(name_index),
|
| - SizeForUnsignedOperand(feedback_slot));
|
| + OperandScale operand_scale = Bytecodes::OperandSizesToScale(
|
| + Bytecodes::SizeForUnsignedOperand(name_index),
|
| + Bytecodes::SizeForUnsignedOperand(feedback_slot));
|
| OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index),
|
| UnsignedOperand(feedback_slot));
|
| return *this;
|
| @@ -402,8 +313,8 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::StoreGlobal(
|
|
|
| BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context,
|
| int slot_index) {
|
| - OperandScale operand_scale = OperandSizesToScale(
|
| - context.SizeOfOperand(), SizeForUnsignedOperand(slot_index));
|
| + OperandScale operand_scale = Bytecodes::OperandSizesToScale(
|
| + context.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(slot_index));
|
| OutputScaled(Bytecode::kLdaContextSlot, operand_scale,
|
| RegisterOperand(context), UnsignedOperand(slot_index));
|
| return *this;
|
| @@ -412,8 +323,8 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadContextSlot(Register context,
|
|
|
| BytecodeArrayBuilder& BytecodeArrayBuilder::StoreContextSlot(Register context,
|
| int slot_index) {
|
| - OperandScale operand_scale = OperandSizesToScale(
|
| - context.SizeOfOperand(), SizeForUnsignedOperand(slot_index));
|
| + OperandScale operand_scale = Bytecodes::OperandSizesToScale(
|
| + context.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(slot_index));
|
| OutputScaled(Bytecode::kStaContextSlot, operand_scale,
|
| RegisterOperand(context), UnsignedOperand(slot_index));
|
| return *this;
|
| @@ -425,8 +336,8 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadLookupSlot(
|
| ? Bytecode::kLdaLookupSlotInsideTypeof
|
| : Bytecode::kLdaLookupSlot;
|
| size_t name_index = GetConstantPoolEntry(name);
|
| - OperandScale operand_scale =
|
| - OperandSizesToScale(SizeForUnsignedOperand(name_index));
|
| + OperandScale operand_scale = Bytecodes::OperandSizesToScale(
|
| + Bytecodes::SizeForUnsignedOperand(name_index));
|
| OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index));
|
| return *this;
|
| }
|
| @@ -435,8 +346,8 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::StoreLookupSlot(
|
| const Handle<String> name, LanguageMode language_mode) {
|
| Bytecode bytecode = BytecodeForStoreLookupSlot(language_mode);
|
| size_t name_index = GetConstantPoolEntry(name);
|
| - OperandScale operand_scale =
|
| - OperandSizesToScale(SizeForUnsignedOperand(name_index));
|
| + OperandScale operand_scale = Bytecodes::OperandSizesToScale(
|
| + Bytecodes::SizeForUnsignedOperand(name_index));
|
| OutputScaled(bytecode, operand_scale, UnsignedOperand(name_index));
|
| return *this;
|
| }
|
| @@ -444,9 +355,9 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::StoreLookupSlot(
|
| BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty(
|
| Register object, const Handle<Name> name, int feedback_slot) {
|
| size_t name_index = GetConstantPoolEntry(name);
|
| - OperandScale operand_scale = OperandSizesToScale(
|
| - object.SizeOfOperand(), SizeForUnsignedOperand(name_index),
|
| - SizeForUnsignedOperand(feedback_slot));
|
| + OperandScale operand_scale = Bytecodes::OperandSizesToScale(
|
| + object.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(name_index),
|
| + Bytecodes::SizeForUnsignedOperand(feedback_slot));
|
| OutputScaled(Bytecode::kLoadIC, operand_scale, RegisterOperand(object),
|
| UnsignedOperand(name_index), UnsignedOperand(feedback_slot));
|
| return *this;
|
| @@ -454,8 +365,8 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::LoadNamedProperty(
|
|
|
| BytecodeArrayBuilder& BytecodeArrayBuilder::LoadKeyedProperty(
|
| Register object, int feedback_slot) {
|
| - OperandScale operand_scale = OperandSizesToScale(
|
| - object.SizeOfOperand(), SizeForUnsignedOperand(feedback_slot));
|
| + OperandScale operand_scale = Bytecodes::OperandSizesToScale(
|
| + object.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(feedback_slot));
|
| OutputScaled(Bytecode::kKeyedLoadIC, operand_scale, RegisterOperand(object),
|
| UnsignedOperand(feedback_slot));
|
| return *this;
|
| @@ -466,9 +377,9 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::StoreNamedProperty(
|
| LanguageMode language_mode) {
|
| Bytecode bytecode = BytecodeForStoreIC(language_mode);
|
| size_t name_index = GetConstantPoolEntry(name);
|
| - OperandScale operand_scale = OperandSizesToScale(
|
| - object.SizeOfOperand(), SizeForUnsignedOperand(name_index),
|
| - SizeForUnsignedOperand(feedback_slot));
|
| + OperandScale operand_scale = Bytecodes::OperandSizesToScale(
|
| + object.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(name_index),
|
| + Bytecodes::SizeForUnsignedOperand(feedback_slot));
|
| OutputScaled(bytecode, operand_scale, RegisterOperand(object),
|
| UnsignedOperand(name_index), UnsignedOperand(feedback_slot));
|
| return *this;
|
| @@ -479,9 +390,9 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::StoreKeyedProperty(
|
| Register object, Register key, int feedback_slot,
|
| LanguageMode language_mode) {
|
| Bytecode bytecode = BytecodeForKeyedStoreIC(language_mode);
|
| - OperandScale operand_scale =
|
| - OperandSizesToScale(object.SizeOfOperand(), key.SizeOfOperand(),
|
| - SizeForUnsignedOperand(feedback_slot));
|
| + OperandScale operand_scale = Bytecodes::OperandSizesToScale(
|
| + object.SizeOfOperand(), key.SizeOfOperand(),
|
| + Bytecodes::SizeForUnsignedOperand(feedback_slot));
|
| OutputScaled(bytecode, operand_scale, RegisterOperand(object),
|
| RegisterOperand(key), UnsignedOperand(feedback_slot));
|
| return *this;
|
| @@ -492,7 +403,7 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CreateClosure(
|
| Handle<SharedFunctionInfo> shared_info, PretenureFlag tenured) {
|
| size_t entry = GetConstantPoolEntry(shared_info);
|
| OperandScale operand_scale =
|
| - OperandSizesToScale(SizeForUnsignedOperand(entry));
|
| + Bytecodes::OperandSizesToScale(Bytecodes::SizeForUnsignedOperand(entry));
|
| OutputScaled(Bytecode::kCreateClosure, operand_scale, UnsignedOperand(entry),
|
| UnsignedOperand(static_cast<size_t>(tenured)));
|
| return *this;
|
| @@ -513,9 +424,10 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArguments(
|
| BytecodeArrayBuilder& BytecodeArrayBuilder::CreateRegExpLiteral(
|
| Handle<String> pattern, int literal_index, int flags) {
|
| size_t pattern_entry = GetConstantPoolEntry(pattern);
|
| - OperandScale operand_scale = OperandSizesToScale(
|
| - SizeForUnsignedOperand(pattern_entry),
|
| - SizeForUnsignedOperand(literal_index), SizeForUnsignedOperand(flags));
|
| + OperandScale operand_scale = Bytecodes::OperandSizesToScale(
|
| + Bytecodes::SizeForUnsignedOperand(pattern_entry),
|
| + Bytecodes::SizeForUnsignedOperand(literal_index),
|
| + Bytecodes::SizeForUnsignedOperand(flags));
|
| OutputScaled(Bytecode::kCreateRegExpLiteral, operand_scale,
|
| UnsignedOperand(pattern_entry), UnsignedOperand(literal_index),
|
| UnsignedOperand(flags));
|
| @@ -526,9 +438,10 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CreateRegExpLiteral(
|
| BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArrayLiteral(
|
| Handle<FixedArray> constant_elements, int literal_index, int flags) {
|
| size_t constant_elements_entry = GetConstantPoolEntry(constant_elements);
|
| - OperandScale operand_scale = OperandSizesToScale(
|
| - SizeForUnsignedOperand(constant_elements_entry),
|
| - SizeForUnsignedOperand(literal_index), SizeForUnsignedOperand(flags));
|
| + OperandScale operand_scale = Bytecodes::OperandSizesToScale(
|
| + Bytecodes::SizeForUnsignedOperand(constant_elements_entry),
|
| + Bytecodes::SizeForUnsignedOperand(literal_index),
|
| + Bytecodes::SizeForUnsignedOperand(flags));
|
| OutputScaled(Bytecode::kCreateArrayLiteral, operand_scale,
|
| UnsignedOperand(constant_elements_entry),
|
| UnsignedOperand(literal_index), UnsignedOperand(flags));
|
| @@ -539,9 +452,10 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CreateArrayLiteral(
|
| BytecodeArrayBuilder& BytecodeArrayBuilder::CreateObjectLiteral(
|
| Handle<FixedArray> constant_properties, int literal_index, int flags) {
|
| size_t constant_properties_entry = GetConstantPoolEntry(constant_properties);
|
| - OperandScale operand_scale = OperandSizesToScale(
|
| - SizeForUnsignedOperand(constant_properties_entry),
|
| - SizeForUnsignedOperand(literal_index), SizeForUnsignedOperand(flags));
|
| + OperandScale operand_scale = Bytecodes::OperandSizesToScale(
|
| + Bytecodes::SizeForUnsignedOperand(constant_properties_entry),
|
| + Bytecodes::SizeForUnsignedOperand(literal_index),
|
| + Bytecodes::SizeForUnsignedOperand(flags));
|
| OutputScaled(Bytecode::kCreateObjectLiteral, operand_scale,
|
| UnsignedOperand(constant_properties_entry),
|
| UnsignedOperand(literal_index), UnsignedOperand(flags));
|
| @@ -550,46 +464,21 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CreateObjectLiteral(
|
|
|
|
|
| BytecodeArrayBuilder& BytecodeArrayBuilder::PushContext(Register context) {
|
| - OperandScale operand_scale = OperandSizesToScale(context.SizeOfOperand());
|
| + OperandScale operand_scale =
|
| + Bytecodes::OperandSizesToScale(context.SizeOfOperand());
|
| OutputScaled(Bytecode::kPushContext, operand_scale, RegisterOperand(context));
|
| return *this;
|
| }
|
|
|
|
|
| BytecodeArrayBuilder& BytecodeArrayBuilder::PopContext(Register context) {
|
| - OperandScale operand_scale = OperandSizesToScale(context.SizeOfOperand());
|
| + OperandScale operand_scale =
|
| + Bytecodes::OperandSizesToScale(context.SizeOfOperand());
|
| OutputScaled(Bytecode::kPopContext, operand_scale, RegisterOperand(context));
|
| return *this;
|
| }
|
|
|
|
|
| -bool BytecodeArrayBuilder::NeedToBooleanCast() {
|
| - if (!LastBytecodeInSameBlock()) {
|
| - return true;
|
| - }
|
| - PreviousBytecodeHelper previous_bytecode(*this);
|
| - switch (previous_bytecode.GetBytecode()) {
|
| - // If the previous bytecode puts a boolean in the accumulator return true.
|
| - case Bytecode::kLdaTrue:
|
| - case Bytecode::kLdaFalse:
|
| - case Bytecode::kLogicalNot:
|
| - case Bytecode::kTestEqual:
|
| - case Bytecode::kTestNotEqual:
|
| - case Bytecode::kTestEqualStrict:
|
| - case Bytecode::kTestLessThan:
|
| - case Bytecode::kTestLessThanOrEqual:
|
| - case Bytecode::kTestGreaterThan:
|
| - case Bytecode::kTestGreaterThanOrEqual:
|
| - case Bytecode::kTestInstanceOf:
|
| - case Bytecode::kTestIn:
|
| - case Bytecode::kForInDone:
|
| - return false;
|
| - default:
|
| - return true;
|
| - }
|
| -}
|
| -
|
| -
|
| BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToJSObject() {
|
| Output(Bytecode::kToObject);
|
| return *this;
|
| @@ -597,26 +486,10 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToJSObject() {
|
|
|
|
|
| BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToName() {
|
| - if (LastBytecodeInSameBlock()) {
|
| - PreviousBytecodeHelper previous_bytecode(*this);
|
| - switch (previous_bytecode.GetBytecode()) {
|
| - case Bytecode::kToName:
|
| - case Bytecode::kTypeOf:
|
| - return *this;
|
| - case Bytecode::kLdaConstant: {
|
| - Handle<Object> object = previous_bytecode.GetConstantForIndexOperand(0);
|
| - if (object->IsName()) return *this;
|
| - break;
|
| - }
|
| - default:
|
| - break;
|
| - }
|
| - }
|
| Output(Bytecode::kToName);
|
| return *this;
|
| }
|
|
|
| -
|
| BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToNumber() {
|
| // TODO(rmcilroy): consider omitting if the preceeding bytecode always returns
|
| // a number.
|
| @@ -626,12 +499,14 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CastAccumulatorToNumber() {
|
|
|
|
|
| BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(BytecodeLabel* label) {
|
| + size_t current_offset = writer()->FlushForOffset();
|
| if (label->is_forward_target()) {
|
| + ZoneVector<uint8_t>* bytecodes = final_stage_writer()->bytecodes();
|
| // An earlier jump instruction refers to this label. Update it's location.
|
| - PatchJump(bytecodes()->end(), bytecodes()->begin() + label->offset());
|
| + PatchJump(bytecodes, current_offset, label->offset());
|
| // Now treat as if the label will only be back referred to.
|
| }
|
| - label->bind_to(bytecodes()->size());
|
| + label->bind_to(current_offset);
|
| LeaveBasicBlock();
|
| return *this;
|
| }
|
| @@ -641,10 +516,11 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::Bind(const BytecodeLabel& target,
|
| BytecodeLabel* label) {
|
| DCHECK(!label->is_bound());
|
| DCHECK(target.is_bound());
|
| + writer()->FlushForOffset();
|
| if (label->is_forward_target()) {
|
| + ZoneVector<uint8_t>* bytecodes = final_stage_writer()->bytecodes();
|
| // An earlier jump instruction refers to this label. Update it's location.
|
| - PatchJump(bytecodes()->begin() + target.offset(),
|
| - bytecodes()->begin() + label->offset());
|
| + PatchJump(bytecodes, target.offset(), label->offset());
|
| // Now treat as if the label will only be back referred to.
|
| }
|
| label->bind_to(target.offset());
|
| @@ -692,77 +568,78 @@ Bytecode BytecodeArrayBuilder::GetJumpWithToBoolean(Bytecode jump_bytecode) {
|
| case Bytecode::kJumpIfFalse:
|
| return Bytecode::kJumpIfToBooleanFalse;
|
| default:
|
| - UNREACHABLE();
|
| + return jump_bytecode;
|
| }
|
| - return Bytecode::kIllegal;
|
| }
|
|
|
| -
|
| -void BytecodeArrayBuilder::PatchIndirectJumpWith8BitOperand(
|
| - const ZoneVector<uint8_t>::iterator& jump_location, int delta) {
|
| - Bytecode jump_bytecode = Bytecodes::FromByte(*jump_location);
|
| +void BytecodeArrayBuilder::PatchJumpWith8BitOperand(
|
| + ZoneVector<uint8_t>* bytecodes, size_t jump_location, int delta) {
|
| + Bytecode jump_bytecode = Bytecodes::FromByte(bytecodes->at(jump_location));
|
| DCHECK(Bytecodes::IsJumpImmediate(jump_bytecode));
|
| - ZoneVector<uint8_t>::iterator operand_location = jump_location + 1;
|
| - DCHECK_EQ(*operand_location, 0);
|
| - if (SizeForSignedOperand(delta) == OperandSize::kByte) {
|
| + size_t operand_location = jump_location + 1;
|
| + DCHECK_EQ(bytecodes->at(operand_location), 0);
|
| + if (Bytecodes::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);
|
| + bytecodes->at(operand_location) = static_cast<uint8_t>(delta);
|
| } else {
|
| // 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(SizeForUnsignedOperand(entry) == OperandSize::kByte);
|
| + DCHECK(Bytecodes::SizeForUnsignedOperand(entry) == OperandSize::kByte);
|
| jump_bytecode = GetJumpWithConstantOperand(jump_bytecode);
|
| - *jump_location = Bytecodes::ToByte(jump_bytecode);
|
| - *operand_location = static_cast<uint8_t>(entry);
|
| + bytecodes->at(jump_location) = Bytecodes::ToByte(jump_bytecode);
|
| + bytecodes->at(operand_location) = static_cast<uint8_t>(entry);
|
| }
|
| }
|
|
|
| -void BytecodeArrayBuilder::PatchIndirectJumpWith16BitOperand(
|
| - const ZoneVector<uint8_t>::iterator& jump_location, int delta) {
|
| - Bytecode jump_bytecode = Bytecodes::FromByte(*jump_location);
|
| +void BytecodeArrayBuilder::PatchJumpWith16BitOperand(
|
| + ZoneVector<uint8_t>* bytecodes, size_t jump_location, int delta) {
|
| + Bytecode jump_bytecode = Bytecodes::FromByte(bytecodes->at(jump_location));
|
| DCHECK(Bytecodes::IsJumpImmediate(jump_bytecode));
|
| - ZoneVector<uint8_t>::iterator operand_location = jump_location + 1;
|
| + size_t operand_location = jump_location + 1;
|
| uint8_t operand_bytes[2];
|
| - if (SizeForSignedOperand(delta) <= OperandSize::kShort) {
|
| + if (Bytecodes::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);
|
| + bytecodes->at(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];
|
| + DCHECK(bytecodes->at(operand_location) == 0 &&
|
| + bytecodes->at(operand_location + 1) == 0);
|
| + bytecodes->at(operand_location++) = operand_bytes[0];
|
| + bytecodes->at(operand_location) = operand_bytes[1];
|
| }
|
|
|
| -void BytecodeArrayBuilder::PatchIndirectJumpWith32BitOperand(
|
| - const ZoneVector<uint8_t>::iterator& jump_location, int delta) {
|
| - DCHECK(Bytecodes::IsJumpImmediate(Bytecodes::FromByte(*jump_location)));
|
| +void BytecodeArrayBuilder::PatchJumpWith32BitOperand(
|
| + ZoneVector<uint8_t>* bytecodes, size_t jump_location, int delta) {
|
| + DCHECK(Bytecodes::IsJumpImmediate(
|
| + Bytecodes::FromByte(bytecodes->at(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) {
|
| + size_t operand_location = jump_location + 1;
|
| + DCHECK(bytecodes->at(operand_location) == 0 &&
|
| + bytecodes->at(operand_location + 1) == 0 &&
|
| + bytecodes->at(operand_location + 2) == 0 &&
|
| + bytecodes->at(operand_location + 3) == 0);
|
| + bytecodes->at(operand_location++) = operand_bytes[0];
|
| + bytecodes->at(operand_location++) = operand_bytes[1];
|
| + bytecodes->at(operand_location++) = operand_bytes[2];
|
| + bytecodes->at(operand_location) = operand_bytes[3];
|
| +}
|
| +
|
| +void BytecodeArrayBuilder::PatchJump(ZoneVector<uint8_t>* bytecodes,
|
| + size_t jump_target, size_t jump_location) {
|
| int delta = static_cast<int>(jump_target - jump_location);
|
| - Bytecode jump_bytecode = Bytecodes::FromByte(*jump_location);
|
| + Bytecode jump_bytecode = Bytecodes::FromByte(bytecodes->at(jump_location));
|
| int prefix_offset = 0;
|
| OperandScale operand_scale = OperandScale::kSingle;
|
| if (Bytecodes::IsPrefixScalingBytecode(jump_bytecode)) {
|
| @@ -771,19 +648,22 @@ void BytecodeArrayBuilder::PatchJump(
|
| delta -= 1;
|
| prefix_offset = 1;
|
| operand_scale = Bytecodes::PrefixBytecodeToOperandScale(jump_bytecode);
|
| - jump_bytecode = Bytecodes::FromByte(*(jump_location + prefix_offset));
|
| + jump_bytecode =
|
| + Bytecodes::FromByte(bytecodes->at(jump_location + prefix_offset));
|
| }
|
|
|
| DCHECK(Bytecodes::IsJump(jump_bytecode));
|
| switch (operand_scale) {
|
| case OperandScale::kSingle:
|
| - PatchIndirectJumpWith8BitOperand(jump_location, delta);
|
| + PatchJumpWith8BitOperand(bytecodes, jump_location, delta);
|
| break;
|
| case OperandScale::kDouble:
|
| - PatchIndirectJumpWith16BitOperand(jump_location + prefix_offset, delta);
|
| + PatchJumpWith16BitOperand(bytecodes, jump_location + prefix_offset,
|
| + delta);
|
| break;
|
| case OperandScale::kQuadruple:
|
| - PatchIndirectJumpWith32BitOperand(jump_location + prefix_offset, delta);
|
| + PatchJumpWith32BitOperand(bytecodes, jump_location + prefix_offset,
|
| + delta);
|
| break;
|
| default:
|
| UNREACHABLE();
|
| @@ -797,25 +677,23 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode,
|
| // Don't emit dead code.
|
| if (exit_seen_in_block_) return *this;
|
|
|
| - // Check if the value in accumulator is boolean, if not choose an
|
| - // appropriate JumpIfToBoolean bytecode.
|
| - if (NeedToBooleanCast()) {
|
| - jump_bytecode = GetJumpWithToBoolean(jump_bytecode);
|
| - }
|
| + // Peephole optimizer will strip this out.
|
| + jump_bytecode = GetJumpWithToBoolean(jump_bytecode);
|
|
|
| if (label->is_bound()) {
|
| // Label has been bound already so this is a backwards jump.
|
| - CHECK_GE(bytecodes()->size(), label->offset());
|
| - CHECK_LE(bytecodes()->size(), static_cast<size_t>(kMaxInt));
|
| - size_t abs_delta = bytecodes()->size() - label->offset();
|
| + size_t current_offset = writer()->FlushForOffset();
|
| + CHECK_GE(current_offset, label->offset());
|
| + CHECK_LE(current_offset, static_cast<size_t>(kMaxInt));
|
| + size_t abs_delta = current_offset - label->offset();
|
| int delta = -static_cast<int>(abs_delta);
|
| - OperandSize operand_size = SizeForSignedOperand(delta);
|
| + OperandSize operand_size = Bytecodes::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, OperandSizesToScale(operand_size),
|
| + OutputScaled(jump_bytecode, Bytecodes::OperandSizesToScale(operand_size),
|
| SignedOperand(delta, operand_size));
|
| } else {
|
| // The label has not yet been bound so this is a forward reference
|
| @@ -824,11 +702,13 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::OutputJump(Bytecode jump_bytecode,
|
| // when the label is bound. The reservation means the maximum size
|
| // of the operand for the constant is known and the jump can
|
| // be emitted into the bytecode stream with space for the operand.
|
| - label->set_referrer(bytecodes()->size());
|
| + size_t offset = writer()->FlushForOffset();
|
| + label->set_referrer(offset);
|
| unbound_jumps_++;
|
| OperandSize reserved_operand_size =
|
| constant_array_builder()->CreateReservedEntry();
|
| - OutputScaled(jump_bytecode, OperandSizesToScale(reserved_operand_size), 0);
|
| + OutputScaled(jump_bytecode,
|
| + Bytecodes::OperandSizesToScale(reserved_operand_size), 0);
|
| }
|
| LeaveBasicBlock();
|
| return *this;
|
| @@ -864,8 +744,7 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::StackCheck(int position) {
|
| if (position != RelocInfo::kNoPosition) {
|
| // We need to attach a non-breakable source position to a stack check,
|
| // so we simply add it as expression position.
|
| - source_position_table_builder_.AddExpressionPosition(bytecodes_.size(),
|
| - position);
|
| + current_node()->source_info().Update({position, false});
|
| }
|
| Output(Bytecode::kStackCheck);
|
| return *this;
|
| @@ -910,7 +789,7 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::Debugger() {
|
| BytecodeArrayBuilder& BytecodeArrayBuilder::ForInPrepare(
|
| Register cache_info_triple) {
|
| OperandScale operand_scale =
|
| - OperandSizesToScale(cache_info_triple.SizeOfOperand());
|
| + Bytecodes::OperandSizesToScale(cache_info_triple.SizeOfOperand());
|
| OutputScaled(Bytecode::kForInPrepare, operand_scale,
|
| RegisterOperand(cache_info_triple));
|
| return *this;
|
| @@ -918,8 +797,8 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::ForInPrepare(
|
|
|
| BytecodeArrayBuilder& BytecodeArrayBuilder::ForInDone(Register index,
|
| Register cache_length) {
|
| - OperandScale operand_scale =
|
| - OperandSizesToScale(index.SizeOfOperand(), cache_length.SizeOfOperand());
|
| + OperandScale operand_scale = Bytecodes::OperandSizesToScale(
|
| + index.SizeOfOperand(), cache_length.SizeOfOperand());
|
| OutputScaled(Bytecode::kForInDone, operand_scale, RegisterOperand(index),
|
| RegisterOperand(cache_length));
|
| return *this;
|
| @@ -928,10 +807,10 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::ForInDone(Register index,
|
| BytecodeArrayBuilder& BytecodeArrayBuilder::ForInNext(
|
| Register receiver, Register index, Register cache_type_array_pair,
|
| int feedback_slot) {
|
| - OperandScale operand_scale =
|
| - OperandSizesToScale(receiver.SizeOfOperand(), index.SizeOfOperand(),
|
| - cache_type_array_pair.SizeOfOperand(),
|
| - SizeForUnsignedOperand(feedback_slot));
|
| + OperandScale operand_scale = Bytecodes::OperandSizesToScale(
|
| + receiver.SizeOfOperand(), index.SizeOfOperand(),
|
| + cache_type_array_pair.SizeOfOperand(),
|
| + Bytecodes::SizeForUnsignedOperand(feedback_slot));
|
| OutputScaled(Bytecode::kForInNext, operand_scale, RegisterOperand(receiver),
|
| RegisterOperand(index), RegisterOperand(cache_type_array_pair),
|
| UnsignedOperand(feedback_slot));
|
| @@ -940,7 +819,8 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::ForInNext(
|
|
|
|
|
| BytecodeArrayBuilder& BytecodeArrayBuilder::ForInStep(Register index) {
|
| - OperandScale operand_scale = OperandSizesToScale(index.SizeOfOperand());
|
| + OperandScale operand_scale =
|
| + Bytecodes::OperandSizesToScale(index.SizeOfOperand());
|
| OutputScaled(Bytecode::kForInStep, operand_scale, RegisterOperand(index));
|
| return *this;
|
| }
|
| @@ -948,7 +828,8 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::ForInStep(Register index) {
|
|
|
| BytecodeArrayBuilder& BytecodeArrayBuilder::SuspendGenerator(
|
| Register generator) {
|
| - OperandScale operand_scale = OperandSizesToScale(generator.SizeOfOperand());
|
| + OperandScale operand_scale =
|
| + Bytecodes::OperandSizesToScale(generator.SizeOfOperand());
|
| OutputScaled(Bytecode::kSuspendGenerator, operand_scale,
|
| RegisterOperand(generator));
|
| return *this;
|
| @@ -957,7 +838,8 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::SuspendGenerator(
|
|
|
| BytecodeArrayBuilder& BytecodeArrayBuilder::ResumeGenerator(
|
| Register generator) {
|
| - OperandScale operand_scale = OperandSizesToScale(generator.SizeOfOperand());
|
| + OperandScale operand_scale =
|
| + Bytecodes::OperandSizesToScale(generator.SizeOfOperand());
|
| OutputScaled(Bytecode::kResumeGenerator, operand_scale,
|
| RegisterOperand(generator));
|
| return *this;
|
| @@ -966,7 +848,8 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::ResumeGenerator(
|
|
|
| BytecodeArrayBuilder& BytecodeArrayBuilder::MarkHandler(int handler_id,
|
| bool will_catch) {
|
| - handler_table_builder()->SetHandlerTarget(handler_id, bytecodes()->size());
|
| + size_t offset = writer()->FlushForOffset();
|
| + handler_table_builder()->SetHandlerTarget(handler_id, offset);
|
| handler_table_builder()->SetPrediction(handler_id, will_catch);
|
| return *this;
|
| }
|
| @@ -974,21 +857,23 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::MarkHandler(int handler_id,
|
|
|
| BytecodeArrayBuilder& BytecodeArrayBuilder::MarkTryBegin(int handler_id,
|
| Register context) {
|
| - handler_table_builder()->SetTryRegionStart(handler_id, bytecodes()->size());
|
| + size_t offset = writer()->FlushForOffset();
|
| + handler_table_builder()->SetTryRegionStart(handler_id, offset);
|
| handler_table_builder()->SetContextRegister(handler_id, context);
|
| return *this;
|
| }
|
|
|
|
|
| BytecodeArrayBuilder& BytecodeArrayBuilder::MarkTryEnd(int handler_id) {
|
| - handler_table_builder()->SetTryRegionEnd(handler_id, bytecodes()->size());
|
| + size_t offset = writer()->FlushForOffset();
|
| + handler_table_builder()->SetTryRegionEnd(handler_id, offset);
|
| return *this;
|
| }
|
|
|
|
|
| void BytecodeArrayBuilder::LeaveBasicBlock() {
|
| - last_block_end_ = bytecodes()->size();
|
| exit_seen_in_block_ = false;
|
| + writer()->LeaveBasicBlock();
|
| }
|
|
|
| void BytecodeArrayBuilder::EnsureReturn() {
|
| @@ -1005,10 +890,10 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::Call(Register callable,
|
| int feedback_slot,
|
| TailCallMode tail_call_mode) {
|
| Bytecode bytecode = BytecodeForCall(tail_call_mode);
|
| - OperandScale operand_scale = OperandSizesToScale(
|
| + OperandScale operand_scale = Bytecodes::OperandSizesToScale(
|
| callable.SizeOfOperand(), receiver_args.SizeOfOperand(),
|
| - SizeForUnsignedOperand(receiver_args_count),
|
| - SizeForUnsignedOperand(feedback_slot));
|
| + Bytecodes::SizeForUnsignedOperand(receiver_args_count),
|
| + Bytecodes::SizeForUnsignedOperand(feedback_slot));
|
| OutputScaled(bytecode, operand_scale, RegisterOperand(callable),
|
| RegisterOperand(receiver_args),
|
| UnsignedOperand(receiver_args_count),
|
| @@ -1023,9 +908,9 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::New(Register constructor,
|
| DCHECK_EQ(0u, arg_count);
|
| first_arg = Register(0);
|
| }
|
| - OperandScale operand_scale = OperandSizesToScale(
|
| + OperandScale operand_scale = Bytecodes::OperandSizesToScale(
|
| constructor.SizeOfOperand(), first_arg.SizeOfOperand(),
|
| - SizeForUnsignedOperand(arg_count));
|
| + Bytecodes::SizeForUnsignedOperand(arg_count));
|
| OutputScaled(Bytecode::kNew, operand_scale, RegisterOperand(constructor),
|
| RegisterOperand(first_arg), UnsignedOperand(arg_count));
|
| return *this;
|
| @@ -1035,7 +920,7 @@ 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(SizeForUnsignedOperand(function_id) <= OperandSize::kShort);
|
| + DCHECK(Bytecodes::SizeForUnsignedOperand(function_id) <= OperandSize::kShort);
|
| if (!first_arg.is_valid()) {
|
| DCHECK_EQ(0u, arg_count);
|
| first_arg = Register(0);
|
| @@ -1043,8 +928,8 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntime(
|
| Bytecode bytecode = IntrinsicsHelper::IsSupported(function_id)
|
| ? Bytecode::kInvokeIntrinsic
|
| : Bytecode::kCallRuntime;
|
| - OperandScale operand_scale = OperandSizesToScale(
|
| - first_arg.SizeOfOperand(), SizeForUnsignedOperand(arg_count));
|
| + OperandScale operand_scale = Bytecodes::OperandSizesToScale(
|
| + first_arg.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(arg_count));
|
| OutputScaled(bytecode, operand_scale, static_cast<uint16_t>(function_id),
|
| RegisterOperand(first_arg), UnsignedOperand(arg_count));
|
| return *this;
|
| @@ -1055,13 +940,13 @@ 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(SizeForUnsignedOperand(function_id) <= OperandSize::kShort);
|
| + DCHECK(Bytecodes::SizeForUnsignedOperand(function_id) <= OperandSize::kShort);
|
| if (!first_arg.is_valid()) {
|
| DCHECK_EQ(0u, arg_count);
|
| first_arg = Register(0);
|
| }
|
| - OperandScale operand_scale = OperandSizesToScale(
|
| - first_arg.SizeOfOperand(), SizeForUnsignedOperand(arg_count),
|
| + OperandScale operand_scale = Bytecodes::OperandSizesToScale(
|
| + first_arg.SizeOfOperand(), Bytecodes::SizeForUnsignedOperand(arg_count),
|
| first_return.SizeOfOperand());
|
| OutputScaled(Bytecode::kCallRuntimeForPair, operand_scale,
|
| static_cast<uint16_t>(function_id), RegisterOperand(first_arg),
|
| @@ -1071,9 +956,10 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CallRuntimeForPair(
|
|
|
| BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime(
|
| int context_index, Register receiver_args, size_t receiver_args_count) {
|
| - OperandScale operand_scale = OperandSizesToScale(
|
| - SizeForUnsignedOperand(context_index), receiver_args.SizeOfOperand(),
|
| - SizeForUnsignedOperand(receiver_args_count));
|
| + OperandScale operand_scale = Bytecodes::OperandSizesToScale(
|
| + Bytecodes::SizeForUnsignedOperand(context_index),
|
| + receiver_args.SizeOfOperand(),
|
| + Bytecodes::SizeForUnsignedOperand(receiver_args_count));
|
| OutputScaled(Bytecode::kCallJSRuntime, operand_scale,
|
| UnsignedOperand(context_index), RegisterOperand(receiver_args),
|
| UnsignedOperand(receiver_args_count));
|
| @@ -1083,7 +969,8 @@ BytecodeArrayBuilder& BytecodeArrayBuilder::CallJSRuntime(
|
|
|
| BytecodeArrayBuilder& BytecodeArrayBuilder::Delete(Register object,
|
| LanguageMode language_mode) {
|
| - OperandScale operand_scale = OperandSizesToScale(object.SizeOfOperand());
|
| + OperandScale operand_scale =
|
| + Bytecodes::OperandSizesToScale(object.SizeOfOperand());
|
| OutputScaled(BytecodeForDelete(language_mode), operand_scale,
|
| RegisterOperand(object));
|
| return *this;
|
| @@ -1096,29 +983,25 @@ size_t BytecodeArrayBuilder::GetConstantPoolEntry(Handle<Object> object) {
|
| void BytecodeArrayBuilder::SetReturnPosition() {
|
| if (return_position_ == RelocInfo::kNoPosition) return;
|
| if (exit_seen_in_block_) return;
|
| - source_position_table_builder_.AddStatementPosition(bytecodes_.size(),
|
| - return_position_);
|
| + current_node()->source_info().Update({return_position_, true});
|
| }
|
|
|
| void BytecodeArrayBuilder::SetStatementPosition(Statement* stmt) {
|
| if (stmt->position() == RelocInfo::kNoPosition) return;
|
| if (exit_seen_in_block_) return;
|
| - source_position_table_builder_.AddStatementPosition(bytecodes_.size(),
|
| - stmt->position());
|
| + current_node()->source_info().Update({stmt->position(), true});
|
| }
|
|
|
| void BytecodeArrayBuilder::SetExpressionPosition(Expression* expr) {
|
| if (expr->position() == RelocInfo::kNoPosition) return;
|
| if (exit_seen_in_block_) return;
|
| - source_position_table_builder_.AddExpressionPosition(bytecodes_.size(),
|
| - expr->position());
|
| + current_node()->source_info().Update({expr->position(), false});
|
| }
|
|
|
| void BytecodeArrayBuilder::SetExpressionAsStatementPosition(Expression* expr) {
|
| if (expr->position() == RelocInfo::kNoPosition) return;
|
| if (exit_seen_in_block_) return;
|
| - source_position_table_builder_.AddStatementPosition(bytecodes_.size(),
|
| - expr->position());
|
| + current_node()->source_info().Update({expr->position(), true});
|
| }
|
|
|
| bool BytecodeArrayBuilder::TemporaryRegisterIsLive(Register reg) const {
|
| @@ -1150,7 +1033,7 @@ bool BytecodeArrayBuilder::OperandIsValid(Bytecode bytecode,
|
| case OperandType::kRuntimeId:
|
| case OperandType::kImm: {
|
| size_t unsigned_value = static_cast<size_t>(operand_value);
|
| - return SizeForUnsignedOperand(unsigned_value) <= operand_size;
|
| + return Bytecodes::SizeForUnsignedOperand(unsigned_value) <= operand_size;
|
| }
|
| case OperandType::kMaybeReg:
|
| if (RegisterFromOperand(operand_value) == Register(0)) {
|
| @@ -1207,25 +1090,6 @@ bool BytecodeArrayBuilder::RegisterIsValid(Register reg,
|
| }
|
| }
|
|
|
| -
|
| -bool BytecodeArrayBuilder::LastBytecodeInSameBlock() const {
|
| - return last_bytecode_start_ < bytecodes()->size() &&
|
| - last_bytecode_start_ >= last_block_end_;
|
| -}
|
| -
|
| -
|
| -bool BytecodeArrayBuilder::IsRegisterInAccumulator(Register reg) {
|
| - if (LastBytecodeInSameBlock()) {
|
| - PreviousBytecodeHelper previous_bytecode(*this);
|
| - Bytecode bytecode = previous_bytecode.GetBytecode();
|
| - if (bytecode == Bytecode::kLdar || bytecode == Bytecode::kStar) {
|
| - return previous_bytecode.GetRegisterOperand(0) == reg;
|
| - }
|
| - }
|
| - return false;
|
| -}
|
| -
|
| -
|
| // static
|
| Bytecode BytecodeArrayBuilder::BytecodeForBinaryOperation(Token::Value op) {
|
| switch (op) {
|
| @@ -1407,65 +1271,6 @@ Bytecode BytecodeArrayBuilder::BytecodeForCall(TailCallMode tail_call_mode) {
|
| return Bytecode::kIllegal;
|
| }
|
|
|
| -// static
|
| -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
|
| -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;
|
| - }
|
| -}
|
| -
|
| -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;
|
| - }
|
| -}
|
| -
|
| -OperandScale BytecodeArrayBuilder::OperandSizesToScale(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);
|
| - // Operand sizes have been scaled before calling this function.
|
| - // Currently all scalable operands are byte sized at
|
| - // OperandScale::kSingle.
|
| - STATIC_ASSERT(static_cast<int>(OperandSize::kByte) ==
|
| - static_cast<int>(OperandScale::kSingle) &&
|
| - static_cast<int>(OperandSize::kShort) ==
|
| - static_cast<int>(OperandScale::kDouble) &&
|
| - static_cast<int>(OperandSize::kQuad) ==
|
| - static_cast<int>(OperandScale::kQuadruple));
|
| - OperandScale operand_scale = static_cast<OperandScale>(result);
|
| - DCHECK(operand_scale == OperandScale::kSingle ||
|
| - operand_scale == OperandScale::kDouble ||
|
| - operand_scale == OperandScale::kQuadruple);
|
| - return operand_scale;
|
| -}
|
| -
|
| uint32_t BytecodeArrayBuilder::RegisterOperand(Register reg) {
|
| return static_cast<uint32_t>(reg.ToOperand());
|
| }
|
|
|