Commit 5716fe8d authored by Ross McIlroy's avatar Ross McIlroy Committed by Commit Bot

[Interpreter] Saving bytecode offset for the prefix bytecode on wide bytecodes

For wide bytecodes, save the bytecode offset as the offset of the prefix
bytecode, rather than the bytecode itself. This means that any code that reads
the bytecode can explicitly know the width of the bytecode at the offset
without having to iterate through the complete bytecode array.

Also simplifies some code in the bytecode analysis that had to work around
the previous approach.

BUG=chromium:753705

Change-Id: I8a42e7cfff27791e39f3452e2b9e52c0608d28cb
Reviewed-on: https://chromium-review.googlesource.com/634003
Commit-Queue: Ross McIlroy <rmcilroy@chromium.org>
Reviewed-by: 's avatarMichael Starzinger <mstarzinger@chromium.org>
Cr-Commit-Position: refs/heads/master@{#47599}
parent 8d2a8e0c
......@@ -272,20 +272,13 @@ void BytecodeAnalysis::Analyze(BailoutId osr_bailout_id) {
int loop_header = iterator.GetJumpTargetOffset();
PushLoop(loop_header, loop_end);
// Normally prefixed bytecodes are treated as if the prefix's offset was
// the actual bytecode's offset. However, the OSR id is the offset of the
// actual JumpLoop bytecode, so we need to find the location of that
// bytecode ignoring the prefix.
int jump_loop_offset = current_offset + iterator.current_prefix_offset();
bool is_osr_loop = (jump_loop_offset == osr_loop_end_offset);
// Check that is_osr_loop is set iff the osr_loop_end_offset is within
// this bytecode.
DCHECK(!is_osr_loop ||
iterator.OffsetWithinBytecode(osr_loop_end_offset));
if (is_osr_loop) {
if (current_offset == osr_loop_end_offset) {
osr_entry_point_ = loop_header;
} else if (current_offset < osr_loop_end_offset) {
// Check we've found the osr_entry_point if we've gone past the
// osr_loop_end_offset. Note, we are iterating the bytecode in reverse,
// so the less than in the check is correct.
DCHECK_NE(-1, osr_entry_point_);
}
// Save the index so that we can do another pass later.
......
......@@ -59,7 +59,7 @@ InterpreterAssembler::InterpreterAssembler(CodeAssemblerState* state,
// Save the bytecode offset immediately if bytecode will make a call along the
// critical path.
if (Bytecodes::MakesCallAlongCriticalPath(bytecode)) {
StoreAndTagRegister(BytecodeOffset(), Register::bytecode_offset());
SaveBytecodeOffset();
}
}
......@@ -86,11 +86,31 @@ Node* InterpreterAssembler::BytecodeOffset() {
if (Bytecodes::MakesCallAlongCriticalPath(bytecode_) && made_call_ &&
(bytecode_offset_.value() ==
Parameter(InterpreterDispatchDescriptor::kBytecodeOffset))) {
bytecode_offset_.Bind(LoadAndUntagRegister(Register::bytecode_offset()));
bytecode_offset_.Bind(ReloadBytecodeOffset());
}
return bytecode_offset_.value();
}
Node* InterpreterAssembler::ReloadBytecodeOffset() {
Node* offset = LoadAndUntagRegister(Register::bytecode_offset());
if (operand_scale() != OperandScale::kSingle) {
// Add one to the offset such that it points to the actual bytecode rather
// than the Wide / ExtraWide prefix bytecode.
offset = IntPtrAdd(offset, IntPtrConstant(1));
}
return offset;
}
void InterpreterAssembler::SaveBytecodeOffset() {
Node* offset = BytecodeOffset();
if (operand_scale() != OperandScale::kSingle) {
// Subtract one from the offset such that it points to the Wide / ExtraWide
// prefix bytecode.
offset = IntPtrSub(BytecodeOffset(), IntPtrConstant(1));
}
StoreAndTagRegister(offset, Register::bytecode_offset());
}
Node* InterpreterAssembler::BytecodeArrayTaggedPointer() {
// Force a re-load of the bytecode array after every call in case the debugger
// has been activated.
......@@ -529,7 +549,7 @@ void InterpreterAssembler::CallPrologue() {
// there are multiple calls in the bytecode handler, you need to spill
// before each of them, unless SaveBytecodeOffset has explicitly been called
// in a path that dominates _all_ of those calls (which we don't track).
StoreAndTagRegister(BytecodeOffset(), Register::bytecode_offset());
SaveBytecodeOffset();
}
if (FLAG_debug_code && !disable_stack_check_across_call_) {
......
......@@ -305,6 +305,8 @@ class V8_EXPORT_PRIVATE InterpreterAssembler : public CodeStubAssembler {
// Save the bytecode offset to the interpreter frame.
void SaveBytecodeOffset();
// Reload the bytecode offset from the interpreter frame.
Node* ReloadBytecodeOffset();
// Updates and returns BytecodeOffset() advanced by the current bytecode's
// size. Traces the exit of the current bytecode.
......
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