[Interpreter]: Basic support for iterating interpreter stack frames for GC.

Adds basic support for iterating interpreter stack frames for GC. Currently
InterpreterStackFrames are treated just like JavaScriptStackFrames since the
JavaScriptFrame::IterateExpressions() will correctly iterate over all the
local / temp interpeter Registers, and will iterate over the
interpreter_entry_trampoline pc address. There is no need to explicitly
iterate over the BytecodeArray object since that is held in a machine
register in the bytecode handler which is marked as kMachTaggedAny by
TurboFan, and so will get iterated appropriately when iterating the
bytecode handler stub's stack frame.

BUG=v8:4280
LOG=N

Review URL: https://codereview.chromium.org/1407513003

Cr-Commit-Position: refs/heads/master@{#31342}
This commit is contained in:
rmcilroy 2015-10-16 08:06:10 -07:00 committed by Commit bot
parent 5c53481233
commit 4b2fffae4c
5 changed files with 47 additions and 21 deletions

View File

@ -234,6 +234,10 @@ inline OptimizedFrame::OptimizedFrame(StackFrameIteratorBase* iterator)
} }
inline InterpretedFrame::InterpretedFrame(StackFrameIteratorBase* iterator)
: JavaScriptFrame(iterator) {}
inline ArgumentsAdaptorFrame::ArgumentsAdaptorFrame( inline ArgumentsAdaptorFrame::ArgumentsAdaptorFrame(
StackFrameIteratorBase* iterator) : JavaScriptFrame(iterator) { StackFrameIteratorBase* iterator) : JavaScriptFrame(iterator) {
} }

View File

@ -439,6 +439,19 @@ StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator,
return JAVA_SCRIPT; return JAVA_SCRIPT;
case Code::OPTIMIZED_FUNCTION: case Code::OPTIMIZED_FUNCTION:
return OPTIMIZED; return OPTIMIZED;
case Code::BUILTIN:
if (!marker->IsSmi()) {
if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) {
// An adapter frame has a special SMI constant for the context and
// is not distinguished through the marker.
return ARGUMENTS_ADAPTOR;
} else {
// The interpreter entry trampoline has a non-SMI marker.
DCHECK(code_obj->is_interpreter_entry_trampoline());
return INTERPRETED;
}
}
break; // Marker encodes the frame type.
case Code::HANDLER: case Code::HANDLER:
if (!marker->IsSmi()) { if (!marker->IsSmi()) {
// Only hydrogen code stub handlers can have a non-SMI marker. // Only hydrogen code stub handlers can have a non-SMI marker.
@ -451,12 +464,6 @@ StackFrame::Type StackFrame::ComputeType(const StackFrameIteratorBase* iterator,
} }
} }
if (StandardFrame::IsArgumentsAdaptorFrame(state->fp)) {
// An adapter frame has a special SMI constant for the context and
// is not distinguished through the marker.
return ARGUMENTS_ADAPTOR;
}
// Didn't find a code object, or the code kind wasn't specific enough. // Didn't find a code object, or the code kind wasn't specific enough.
// The marker should encode the frame type. // The marker should encode the frame type.
return static_cast<StackFrame::Type>(Smi::cast(marker)->value()); return static_cast<StackFrame::Type>(Smi::cast(marker)->value());

View File

@ -104,6 +104,7 @@ class StackHandler BASE_EMBEDDED {
V(EXIT, ExitFrame) \ V(EXIT, ExitFrame) \
V(JAVA_SCRIPT, JavaScriptFrame) \ V(JAVA_SCRIPT, JavaScriptFrame) \
V(OPTIMIZED, OptimizedFrame) \ V(OPTIMIZED, OptimizedFrame) \
V(INTERPRETED, InterpretedFrame) \
V(STUB, StubFrame) \ V(STUB, StubFrame) \
V(STUB_FAILURE_TRAMPOLINE, StubFailureTrampolineFrame) \ V(STUB_FAILURE_TRAMPOLINE, StubFailureTrampolineFrame) \
V(INTERNAL, InternalFrame) \ V(INTERNAL, InternalFrame) \
@ -702,6 +703,17 @@ class OptimizedFrame : public JavaScriptFrame {
}; };
class InterpretedFrame : public JavaScriptFrame {
virtual Type type() const { return INTERPRETED; }
protected:
inline explicit InterpretedFrame(StackFrameIteratorBase* iterator);
private:
friend class StackFrameIteratorBase;
};
// Arguments adaptor frames are automatically inserted below // Arguments adaptor frames are automatically inserted below
// JavaScript frames when the actual number of parameters does not // JavaScript frames when the actual number of parameters does not
// match the formal number of parameters. // match the formal number of parameters.

View File

@ -4978,12 +4978,8 @@ bool Code::IsCodeStubOrIC() {
bool Code::IsJavaScriptCode() { bool Code::IsJavaScriptCode() {
if (kind() == FUNCTION || kind() == OPTIMIZED_FUNCTION) { return kind() == FUNCTION || kind() == OPTIMIZED_FUNCTION ||
return true; is_interpreter_entry_trampoline();
}
Handle<Code> interpreter_entry =
GetIsolate()->builtins()->InterpreterEntryTrampoline();
return interpreter_entry.location() != nullptr && *interpreter_entry == this;
} }
@ -5032,6 +5028,12 @@ inline bool Code::is_hydrogen_stub() {
} }
inline bool Code::is_interpreter_entry_trampoline() {
Handle<Code> interpreter_entry =
GetIsolate()->builtins()->InterpreterEntryTrampoline();
return interpreter_entry.location() != nullptr && *interpreter_entry == this;
}
inline void Code::set_is_crankshafted(bool value) { inline void Code::set_is_crankshafted(bool value) {
int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset); int previous = READ_UINT32_FIELD(this, kKindSpecificFlags2Offset);
int updated = IsCrankshaftedField::update(previous, value); int updated = IsCrankshaftedField::update(previous, value);

View File

@ -4899,6 +4899,7 @@ class Code: public HeapObject {
inline bool is_to_boolean_ic_stub(); inline bool is_to_boolean_ic_stub();
inline bool is_keyed_stub(); inline bool is_keyed_stub();
inline bool is_optimized_code(); inline bool is_optimized_code();
inline bool is_interpreter_entry_trampoline();
inline bool embeds_maps_weakly(); inline bool embeds_maps_weakly();
inline bool IsCodeStubOrIC(); inline bool IsCodeStubOrIC();