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

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

Issue 2358423002: Version 5.5.251.1 (cherry-pick) (Closed)
Patch Set: Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/interpreter/bytecode-array-writer.h ('k') | src/interpreter/bytecode-dead-code-optimizer.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/interpreter/bytecode-array-writer.cc
diff --git a/src/interpreter/bytecode-array-writer.cc b/src/interpreter/bytecode-array-writer.cc
index 02948dc5af895c445f79eb775e933adb86ee71a3..93db4530165686b6f8cf9954f5267c5f1bdd9647 100644
--- a/src/interpreter/bytecode-array-writer.cc
+++ b/src/interpreter/bytecode-array-writer.cc
@@ -21,23 +21,27 @@ BytecodeArrayWriter::BytecodeArrayWriter(
Zone* zone, ConstantArrayBuilder* constant_array_builder,
SourcePositionTableBuilder::RecordingMode source_position_mode)
: bytecodes_(zone),
+ max_register_count_(0),
unbound_jumps_(0),
source_position_table_builder_(zone, source_position_mode),
- constant_array_builder_(constant_array_builder) {
- bytecodes_.reserve(512); // Derived via experimentation.
-}
+ constant_array_builder_(constant_array_builder) {}
// override
BytecodeArrayWriter::~BytecodeArrayWriter() {}
// override
Handle<BytecodeArray> BytecodeArrayWriter::ToBytecodeArray(
- Isolate* isolate, int register_count, int parameter_count,
+ Isolate* isolate, int fixed_register_count, int parameter_count,
Handle<FixedArray> handler_table) {
DCHECK_EQ(0, unbound_jumps_);
int bytecode_size = static_cast<int>(bytecodes()->size());
- int frame_size = register_count * kPointerSize;
+
+ // 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_used = max_register_count() * kPointerSize;
+ int frame_size = std::max(frame_size_for_locals, frame_size_used);
Handle<FixedArray> constant_pool =
constant_array_builder()->ToFixedArray(isolate);
Handle<BytecodeArray> bytecode_array = isolate->factory()->NewBytecodeArray(
@@ -100,48 +104,116 @@ void BytecodeArrayWriter::UpdateSourcePositionTable(
}
}
+namespace {
+
+OperandScale ScaleForScalableByteOperand(OperandSize operand_size) {
+ STATIC_ASSERT(static_cast<int>(OperandSize::kByte) ==
+ static_cast<int>(OperandScale::kSingle));
+ STATIC_ASSERT(static_cast<int>(OperandSize::kShort) ==
+ static_cast<int>(OperandScale::kDouble));
+ STATIC_ASSERT(static_cast<int>(OperandSize::kQuad) ==
+ static_cast<int>(OperandScale::kQuadruple));
+ return static_cast<OperandScale>(operand_size);
+}
+
+OperandScale OperandScaleForScalableSignedByte(uint32_t operand_value) {
+ int32_t signed_operand = static_cast<int32_t>(operand_value);
+ OperandSize bytes_required = Bytecodes::SizeForSignedOperand(signed_operand);
+ return ScaleForScalableByteOperand(bytes_required);
+}
+
+OperandScale OperandScaleForScalableUnsignedByte(uint32_t operand_value) {
+ OperandSize bytes_required = Bytecodes::SizeForUnsignedOperand(operand_value);
+ return ScaleForScalableByteOperand(bytes_required);
+}
+
+OperandScale GetOperandScale(const BytecodeNode* const node) {
+ const OperandTypeInfo* operand_type_infos =
+ Bytecodes::GetOperandTypeInfos(node->bytecode());
+ OperandScale operand_scale = OperandScale::kSingle;
+ int operand_count = node->operand_count();
+ for (int i = 0; i < operand_count; ++i) {
+ switch (operand_type_infos[i]) {
+ case OperandTypeInfo::kScalableSignedByte: {
+ uint32_t operand = node->operand(i);
+ operand_scale =
+ std::max(operand_scale, OperandScaleForScalableSignedByte(operand));
+ break;
+ }
+ case OperandTypeInfo::kScalableUnsignedByte: {
+ uint32_t operand = node->operand(i);
+ operand_scale = std::max(operand_scale,
+ OperandScaleForScalableUnsignedByte(operand));
+ break;
+ }
+ case OperandTypeInfo::kFixedUnsignedByte:
+ case OperandTypeInfo::kFixedUnsignedShort:
+ break;
+ case OperandTypeInfo::kNone:
+ UNREACHABLE();
+ break;
+ }
+ }
+ return operand_scale;
+}
+
+} // namespace
+
void BytecodeArrayWriter::EmitBytecode(const BytecodeNode* const node) {
DCHECK_NE(node->bytecode(), Bytecode::kIllegal);
- Bytecode bytecode = node->bytecode();
- OperandScale operand_scale = node->operand_scale();
+ uint8_t buffer[kMaxSizeOfPackedBytecode];
+ uint8_t* buffer_limit = buffer;
+ OperandScale operand_scale = GetOperandScale(node);
if (operand_scale != OperandScale::kSingle) {
Bytecode prefix = Bytecodes::OperandScaleToPrefixBytecode(operand_scale);
- bytecodes()->push_back(Bytecodes::ToByte(prefix));
+ *buffer_limit++ = Bytecodes::ToByte(prefix);
}
- bytecodes()->push_back(Bytecodes::ToByte(bytecode));
+
+ Bytecode bytecode = node->bytecode();
+ *buffer_limit++ = Bytecodes::ToByte(bytecode);
const uint32_t* const operands = node->operands();
- const int operand_count = node->operand_count();
- const OperandSize* operand_sizes =
- Bytecodes::GetOperandSizes(bytecode, operand_scale);
+ const OperandType* operand_types = Bytecodes::GetOperandTypes(bytecode);
+ const int operand_count = Bytecodes::NumberOfOperands(bytecode);
for (int i = 0; i < operand_count; ++i) {
- switch (operand_sizes[i]) {
+ OperandSize operand_size =
+ Bytecodes::SizeOfOperand(operand_types[i], operand_scale);
+ switch (operand_size) {
case OperandSize::kNone:
UNREACHABLE();
break;
case OperandSize::kByte:
- bytecodes()->push_back(static_cast<uint8_t>(operands[i]));
+ *buffer_limit++ = static_cast<uint8_t>(operands[i]);
break;
case OperandSize::kShort: {
- const uint8_t* raw_operand =
- reinterpret_cast<const uint8_t*>(&operands[i]);
- bytecodes()->push_back(raw_operand[0]);
- bytecodes()->push_back(raw_operand[1]);
+ WriteUnalignedUInt16(buffer_limit, operands[i]);
+ buffer_limit += 2;
break;
}
case OperandSize::kQuad: {
- const uint8_t* raw_operand =
- reinterpret_cast<const uint8_t*>(&operands[i]);
- bytecodes()->push_back(raw_operand[0]);
- bytecodes()->push_back(raw_operand[1]);
- bytecodes()->push_back(raw_operand[2]);
- bytecodes()->push_back(raw_operand[3]);
+ WriteUnalignedUInt32(buffer_limit, operands[i]);
+ buffer_limit += 4;
break;
}
}
+
+ int count = Bytecodes::GetNumberOfRegistersRepresentedBy(operand_types[i]);
+ if (count == 0) {
+ continue;
+ }
+ // NB operand_types is terminated by OperandType::kNone so
+ // operand_types[i + 1] is valid whilst i < operand_count.
+ if (operand_types[i + 1] == OperandType::kRegCount) {
+ count = static_cast<int>(operands[i]);
+ }
+ Register reg = Register::FromOperand(static_cast<int32_t>(operands[i]));
+ max_register_count_ = std::max(max_register_count_, reg.index() + count);
}
+
+ DCHECK_LE(buffer_limit, buffer + sizeof(buffer));
+ bytecodes()->insert(bytecodes()->end(), buffer, buffer_limit);
}
// static
@@ -175,17 +247,18 @@ void BytecodeArrayWriter::PatchJumpWith8BitOperand(size_t jump_location,
DCHECK(Bytecodes::IsJumpImmediate(jump_bytecode));
size_t operand_location = jump_location + 1;
DCHECK_EQ(bytecodes()->at(operand_location), k8BitJumpPlaceholder);
- if (Bytecodes::ScaleForSignedOperand(delta) == OperandScale::kSingle) {
- // The jump fits within the range of an Imm8 operand, so cancel
+ 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);
bytecodes()->at(operand_location) = static_cast<uint8_t>(delta);
} else {
- // The jump does not fit within the range of an Imm8 operand, so
+ // The jump does not fit within the range of an Imm operand, so
// commit reservation putting the offset into the constant pool,
// and update the jump instruction and operand.
size_t entry = constant_array_builder()->CommitReservedEntry(
OperandSize::kByte, Smi::FromInt(delta));
+ DCHECK_LE(entry, kMaxUInt32);
DCHECK_EQ(Bytecodes::SizeForUnsignedOperand(static_cast<uint32_t>(entry)),
OperandSize::kByte);
jump_bytecode = GetJumpWithConstantOperand(jump_bytecode);
@@ -200,21 +273,14 @@ void BytecodeArrayWriter::PatchJumpWith16BitOperand(size_t jump_location,
DCHECK(Bytecodes::IsJumpImmediate(jump_bytecode));
size_t operand_location = jump_location + 1;
uint8_t operand_bytes[2];
- if (Bytecodes::ScaleForSignedOperand(delta) <= OperandScale::kDouble) {
- // The jump fits within the range of an Imm16 operand, so cancel
- // the reservation and jump directly.
+ if (Bytecodes::SizeForSignedOperand(delta) <= OperandSize::kShort) {
constant_array_builder()->DiscardReservedEntry(OperandSize::kShort);
WriteUnalignedUInt16(operand_bytes, static_cast<uint16_t>(delta));
} else {
- // The jump does not fit within the range of an Imm16 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::kShort, Smi::FromInt(delta));
- DCHECK_EQ(Bytecodes::SizeForUnsignedOperand(static_cast<uint32_t>(entry)),
- OperandSize::kShort);
jump_bytecode = GetJumpWithConstantOperand(jump_bytecode);
bytecodes()->at(jump_location) = Bytecodes::ToByte(jump_bytecode);
+ size_t entry = constant_array_builder()->CommitReservedEntry(
+ OperandSize::kShort, Smi::FromInt(delta));
WriteUnalignedUInt16(operand_bytes, static_cast<uint16_t>(entry));
}
DCHECK(bytecodes()->at(operand_location) == k8BitJumpPlaceholder &&
@@ -285,8 +351,8 @@ void BytecodeArrayWriter::EmitJump(BytecodeNode* node, BytecodeLabel* label) {
// Label has been bound already so this is a backwards jump.
size_t abs_delta = current_offset - label->offset();
int delta = -static_cast<int>(abs_delta);
- OperandScale operand_scale = Bytecodes::ScaleForSignedOperand(delta);
- if (operand_scale > OperandScale::kSingle) {
+ 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;
« no previous file with comments | « src/interpreter/bytecode-array-writer.h ('k') | src/interpreter/bytecode-dead-code-optimizer.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698