Commit bb7bb8b7 authored by Jaroslav Sevcik's avatar Jaroslav Sevcik Committed by Commit Bot

Introduce bytecode array abstraction.

This is to allow instantiating things like bytecode array iterator for
accessing both on-heap and off-heap bytecode arrays.

Bug: v8:7790
Change-Id: I8dbd0884f79923d69dbc8b168d3a4a200eab14b2
Reviewed-on: https://chromium-review.googlesource.com/c/v8/v8/+/1640199
Commit-Queue: Jaroslav Sevcik <jarin@chromium.org>
Reviewed-by: 's avatarRoss McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarGeorg Neis <neis@chromium.org>
Reviewed-by: 's avatarYang Guo <yangguo@chromium.org>
Reviewed-by: 's avatarMaya Lekova <mslekova@chromium.org>
Cr-Commit-Position: refs/heads/master@{#62266}
parent bd88c759
......@@ -204,9 +204,9 @@ void UpdateInLiveness(Bytecode bytecode, BytecodeLivenessState& in_liveness,
void UpdateOutLiveness(Bytecode bytecode, BytecodeLivenessState& out_liveness,
BytecodeLivenessState* next_bytecode_in_liveness,
const interpreter::BytecodeArrayAccessor& accessor,
Handle<BytecodeArray> bytecode_array,
const BytecodeLivenessMap& liveness_map) {
int current_offset = accessor.current_offset();
const Handle<BytecodeArray>& bytecode_array = accessor.bytecode_array();
// Special case Suspend and Resume to just pass through liveness.
if (bytecode == Bytecode::kSuspendGenerator ||
......@@ -264,9 +264,10 @@ void UpdateOutLiveness(Bytecode bytecode, BytecodeLivenessState& out_liveness,
void UpdateLiveness(Bytecode bytecode, BytecodeLiveness& liveness,
BytecodeLivenessState** next_bytecode_in_liveness,
const interpreter::BytecodeArrayAccessor& accessor,
Handle<BytecodeArray> bytecode_array,
const BytecodeLivenessMap& liveness_map) {
UpdateOutLiveness(bytecode, *liveness.out, *next_bytecode_in_liveness,
accessor, liveness_map);
accessor, bytecode_array, liveness_map);
liveness.in->CopyFrom(*liveness.out);
UpdateInLiveness(bytecode, *liveness.in, accessor);
......@@ -426,7 +427,7 @@ void BytecodeAnalysis::Analyze(BailoutId osr_bailout_id) {
BytecodeLiveness& liveness = liveness_map_.InitializeLiveness(
current_offset, bytecode_array()->register_count(), zone());
UpdateLiveness(bytecode, liveness, &next_bytecode_in_liveness, iterator,
liveness_map_);
bytecode_array(), liveness_map_);
}
}
......@@ -489,12 +490,13 @@ void BytecodeAnalysis::Analyze(BailoutId osr_bailout_id) {
BytecodeLiveness& liveness = liveness_map_.GetLiveness(current_offset);
UpdateLiveness(bytecode, liveness, &next_bytecode_in_liveness, iterator,
liveness_map_);
bytecode_array(), liveness_map_);
}
// Now we are at the loop header. Since the in-liveness of the header
// can't change, we need only to update the out-liveness.
UpdateOutLiveness(iterator.current_bytecode(), *header_liveness.out,
next_bytecode_in_liveness, iterator, liveness_map_);
next_bytecode_in_liveness, iterator, bytecode_array(),
liveness_map_);
}
// Process the generator switch statement separately, once the loops are done.
......@@ -533,7 +535,7 @@ void BytecodeAnalysis::Analyze(BailoutId osr_bailout_id) {
DCHECK_NE(bytecode, Bytecode::kJumpLoop);
UpdateLiveness(bytecode, liveness, &next_bytecode_in_liveness, iterator,
liveness_map_);
bytecode_array(), liveness_map_);
}
}
}
......@@ -758,14 +760,14 @@ bool BytecodeAnalysis::ResumeJumpTargetLeavesResolveSuspendIds(
valid = false;
} else {
// Make sure we're resuming to a Resume bytecode
interpreter::BytecodeArrayAccessor assessor(bytecode_array(),
interpreter::BytecodeArrayAccessor accessor(bytecode_array(),
target.target_offset());
if (assessor.current_bytecode() != Bytecode::kResumeGenerator) {
if (accessor.current_bytecode() != Bytecode::kResumeGenerator) {
PrintF(stderr,
"Expected resume target for id %d, offset %d, to be "
"ResumeGenerator, but found %s\n",
target.suspend_id(), target.target_offset(),
Bytecodes::ToString(assessor.current_bytecode()));
Bytecodes::ToString(accessor.current_bytecode()));
valid = false;
}
......@@ -820,7 +822,7 @@ bool BytecodeAnalysis::LivenessIsValid() {
previous_liveness.CopyFrom(*liveness.out);
UpdateOutLiveness(bytecode, *liveness.out, next_bytecode_in_liveness,
iterator, liveness_map_);
iterator, bytecode_array(), liveness_map_);
// UpdateOutLiveness skips kJumpLoop, so we update it manually.
if (bytecode == Bytecode::kJumpLoop) {
int target_offset = iterator.GetJumpTargetOffset();
......
......@@ -397,9 +397,10 @@ Hints SerializerForBackgroundCompilation::Run() {
class ExceptionHandlerMatcher {
public:
explicit ExceptionHandlerMatcher(
BytecodeArrayIterator const& bytecode_iterator)
BytecodeArrayIterator const& bytecode_iterator,
Handle<BytecodeArray> bytecode_array)
: bytecode_iterator_(bytecode_iterator) {
HandlerTable table(*bytecode_iterator_.bytecode_array());
HandlerTable table(*bytecode_array);
for (int i = 0, n = table.NumberOfRangeEntries(); i < n; ++i) {
handlers_.insert(table.GetRangeHandler(i));
}
......@@ -427,7 +428,7 @@ void SerializerForBackgroundCompilation::TraverseBytecode() {
broker(), handle(environment()->function().shared->GetBytecodeArray(),
broker()->isolate()));
BytecodeArrayIterator iterator(bytecode_array.object());
ExceptionHandlerMatcher handler_matcher(iterator);
ExceptionHandlerMatcher handler_matcher(iterator, bytecode_array.object());
for (; !iterator.done(); iterator.Advance()) {
IncorporateJumpTargetEnvironment(iterator.current_offset());
......
......@@ -14,8 +14,48 @@ namespace v8 {
namespace internal {
namespace interpreter {
namespace {
class OnHeapBytecodeArray final : public AbstractBytecodeArray {
public:
explicit OnHeapBytecodeArray(Handle<BytecodeArray> bytecode_array)
: array_(bytecode_array) {}
int length() const override { return array_->length(); }
int parameter_count() const override { return array_->parameter_count(); }
uint8_t get(int index) const override { return array_->get(index); }
void set(int index, uint8_t value) override {
return array_->set(index, value);
}
Address GetFirstBytecodeAddress() const override {
return array_->GetFirstBytecodeAddress();
}
Handle<Object> GetConstantAtIndex(int index,
Isolate* isolate) const override {
return handle(array_->constant_pool().get(index), isolate);
}
bool IsConstantAtIndexSmi(int index) const override {
return array_->constant_pool().get(index).IsSmi();
}
Smi GetConstantAtIndexAsSmi(int index) const override {
return Smi::cast(array_->constant_pool().get(index));
}
private:
Handle<BytecodeArray> array_;
};
} // namespace
BytecodeArrayAccessor::BytecodeArrayAccessor(
Handle<BytecodeArray> bytecode_array, int initial_offset)
AbstractBytecodeArray* bytecode_array, int initial_offset)
: bytecode_array_(bytecode_array),
bytecode_offset_(initial_offset),
operand_scale_(OperandScale::kSingle),
......@@ -23,6 +63,11 @@ BytecodeArrayAccessor::BytecodeArrayAccessor(
UpdateOperandScale();
}
BytecodeArrayAccessor::BytecodeArrayAccessor(
Handle<BytecodeArray> bytecode_array, int initial_offset)
: BytecodeArrayAccessor(new OnHeapBytecodeArray(bytecode_array),
initial_offset) {}
void BytecodeArrayAccessor::SetOffset(int offset) {
bytecode_offset_ = offset;
UpdateOperandScale();
......@@ -33,12 +78,12 @@ void BytecodeArrayAccessor::ApplyDebugBreak() {
// scaling prefix, which we can patch with the matching debug-break
// variant.
interpreter::Bytecode bytecode =
interpreter::Bytecodes::FromByte(bytecode_array_->get(bytecode_offset_));
interpreter::Bytecodes::FromByte(bytecode_array()->get(bytecode_offset_));
if (interpreter::Bytecodes::IsDebugBreak(bytecode)) return;
interpreter::Bytecode debugbreak =
interpreter::Bytecodes::GetDebugBreak(bytecode);
bytecode_array_->set(bytecode_offset_,
interpreter::Bytecodes::ToByte(debugbreak));
bytecode_array()->set(bytecode_offset_,
interpreter::Bytecodes::ToByte(debugbreak));
}
void BytecodeArrayAccessor::UpdateOperandScale() {
......@@ -199,15 +244,15 @@ Runtime::FunctionId BytecodeArrayAccessor::GetIntrinsicIdOperand(
Handle<Object> BytecodeArrayAccessor::GetConstantAtIndex(
int index, Isolate* isolate) const {
return handle(bytecode_array()->constant_pool().get(index), isolate);
return bytecode_array()->GetConstantAtIndex(index, isolate);
}
bool BytecodeArrayAccessor::IsConstantAtIndexSmi(int index) const {
return bytecode_array()->constant_pool().get(index).IsSmi();
return bytecode_array()->IsConstantAtIndexSmi(index);
}
Smi BytecodeArrayAccessor::GetConstantAtIndexAsSmi(int index) const {
return Smi::cast(bytecode_array()->constant_pool().get(index));
return bytecode_array()->GetConstantAtIndexAsSmi(index);
}
Handle<Object> BytecodeArrayAccessor::GetConstantForIndexOperand(
......
......@@ -65,8 +65,27 @@ class V8_EXPORT_PRIVATE JumpTableTargetOffsets final {
int case_value_base_;
};
class V8_EXPORT_PRIVATE AbstractBytecodeArray {
public:
virtual int length() const = 0;
virtual int parameter_count() const = 0;
virtual uint8_t get(int index) const = 0;
virtual void set(int index, uint8_t value) = 0;
virtual Address GetFirstBytecodeAddress() const = 0;
virtual Handle<Object> GetConstantAtIndex(int index,
Isolate* isolate) const = 0;
virtual bool IsConstantAtIndexSmi(int index) const = 0;
virtual Smi GetConstantAtIndexAsSmi(int index) const = 0;
virtual ~AbstractBytecodeArray() = default;
};
class V8_EXPORT_PRIVATE BytecodeArrayAccessor {
public:
BytecodeArrayAccessor(AbstractBytecodeArray* bytecode_array,
int initial_offset);
BytecodeArrayAccessor(Handle<BytecodeArray> bytecode_array,
int initial_offset);
......@@ -79,8 +98,8 @@ class V8_EXPORT_PRIVATE BytecodeArrayAccessor {
int current_offset() const { return bytecode_offset_; }
OperandScale current_operand_scale() const { return operand_scale_; }
int current_prefix_offset() const { return prefix_offset_; }
const Handle<BytecodeArray>& bytecode_array() const {
return bytecode_array_;
AbstractBytecodeArray* bytecode_array() const {
return bytecode_array_.get();
}
uint32_t GetFlagOperand(int operand_index) const;
......@@ -126,7 +145,7 @@ class V8_EXPORT_PRIVATE BytecodeArrayAccessor {
void UpdateOperandScale();
Handle<BytecodeArray> bytecode_array_;
std::unique_ptr<AbstractBytecodeArray> bytecode_array_;
int bytecode_offset_;
OperandScale operand_scale_;
int prefix_offset_;
......
......@@ -10,6 +10,10 @@ namespace v8 {
namespace internal {
namespace interpreter {
BytecodeArrayIterator::BytecodeArrayIterator(
AbstractBytecodeArray* bytecode_array)
: BytecodeArrayAccessor(bytecode_array, 0) {}
BytecodeArrayIterator::BytecodeArrayIterator(
Handle<BytecodeArray> bytecode_array)
: BytecodeArrayAccessor(bytecode_array, 0) {}
......
......@@ -14,7 +14,8 @@ namespace interpreter {
class V8_EXPORT_PRIVATE BytecodeArrayIterator final
: public BytecodeArrayAccessor {
public:
explicit BytecodeArrayIterator(Handle<BytecodeArray> bytecode_array);
explicit BytecodeArrayIterator(AbstractBytecodeArray* array);
explicit BytecodeArrayIterator(Handle<BytecodeArray> array);
void Advance();
bool done() const;
......
......@@ -10,12 +10,22 @@ namespace v8 {
namespace internal {
namespace interpreter {
BytecodeArrayRandomIterator::BytecodeArrayRandomIterator(
AbstractBytecodeArray* bytecode_array, Zone* zone)
: BytecodeArrayAccessor(bytecode_array, 0), offsets_(zone) {
Initialize();
}
BytecodeArrayRandomIterator::BytecodeArrayRandomIterator(
Handle<BytecodeArray> bytecode_array, Zone* zone)
: BytecodeArrayAccessor(bytecode_array, 0), offsets_(zone) {
Initialize();
}
void BytecodeArrayRandomIterator::Initialize() {
// Run forwards through the bytecode array to determine the offset of each
// bytecode.
while (current_offset() < bytecode_array->length()) {
while (current_offset() < bytecode_array()->length()) {
offsets_.push_back(current_offset());
SetOffset(current_offset() + current_bytecode_size());
}
......
......@@ -16,6 +16,8 @@ namespace interpreter {
class V8_EXPORT_PRIVATE BytecodeArrayRandomIterator final
: public BytecodeArrayAccessor {
public:
explicit BytecodeArrayRandomIterator(AbstractBytecodeArray* bytecode_array,
Zone* zone);
explicit BytecodeArrayRandomIterator(Handle<BytecodeArray> bytecode_array,
Zone* zone);
......@@ -66,6 +68,7 @@ class V8_EXPORT_PRIVATE BytecodeArrayRandomIterator final
ZoneVector<int> offsets_;
int current_index_;
void Initialize();
void UpdateOffsetFromIndex();
DISALLOW_COPY_AND_ASSIGN(BytecodeArrayRandomIterator);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment