Commit 25a9364f authored by mstarzinger's avatar mstarzinger Committed by Commit bot

[runtime] Change JavaScriptFrame::GetFunctions interface.

This adapts the aformentioned interface to no longer return a list of
{JSFunction} objects, but {SharedFunctionInfo} objects instead. Since
deoptimization data only contains the latter as literals, this by now
represents the fast path. All call sites requiring the former can use
the slow path via {JavaScriptFrame::Summarize} instead.

R=jarin@chromium.org

Review-Url: https://codereview.chromium.org/2626213002
Cr-Commit-Position: refs/heads/master@{#42311}
parent 369e5c8c
......@@ -844,10 +844,10 @@ static Handle<Object> ArgumentsForInlinedFunction(
static int FindFunctionInFrame(JavaScriptFrame* frame,
Handle<JSFunction> function) {
DisallowHeapAllocation no_allocation;
List<JSFunction*> functions(2);
frame->GetFunctions(&functions);
for (int i = functions.length() - 1; i >= 0; i--) {
if (functions[i] == *function) return i;
List<FrameSummary> frames(2);
frame->Summarize(&frames);
for (int i = frames.length() - 1; i >= 0; i--) {
if (*frames[i].function() == *function) return i;
}
return -1;
}
......@@ -951,19 +951,16 @@ static inline bool AllowAccessToFunction(Context* current_context,
class FrameFunctionIterator {
public:
FrameFunctionIterator(Isolate* isolate, const DisallowHeapAllocation& promise)
: isolate_(isolate),
frame_iterator_(isolate),
functions_(2),
index_(0) {
GetFunctions();
: isolate_(isolate), frame_iterator_(isolate), frames_(2), index_(0) {
GetFrames();
}
JSFunction* next() {
while (true) {
if (functions_.length() == 0) return NULL;
JSFunction* next_function = functions_[index_];
if (frames_.length() == 0) return NULL;
JSFunction* next_function = *frames_[index_].function();
index_--;
if (index_ < 0) {
GetFunctions();
GetFrames();
}
// Skip functions from other origins.
if (!AllowAccessToFunction(isolate_->context(), next_function)) continue;
......@@ -984,18 +981,18 @@ class FrameFunctionIterator {
}
private:
void GetFunctions() {
functions_.Rewind(0);
void GetFrames() {
frames_.Rewind(0);
if (frame_iterator_.done()) return;
JavaScriptFrame* frame = frame_iterator_.frame();
frame->GetFunctions(&functions_);
DCHECK(functions_.length() > 0);
frame->Summarize(&frames_);
DCHECK(frames_.length() > 0);
frame_iterator_.Advance();
index_ = functions_.length() - 1;
index_ = frames_.length() - 1;
}
Isolate* isolate_;
JavaScriptFrameIterator frame_iterator_;
List<JSFunction*> functions_;
List<FrameSummary> frames_;
int index_;
};
......
......@@ -926,7 +926,7 @@ bool JavaScriptFrame::IsConstructor() const {
bool JavaScriptFrame::HasInlinedFrames() const {
List<JSFunction*> functions(1);
List<SharedFunctionInfo*> functions(1);
GetFunctions(&functions);
return functions.length() > 1;
}
......@@ -959,10 +959,9 @@ Address JavaScriptFrame::GetCallerStackPointer() const {
return fp() + StandardFrameConstants::kCallerSPOffset;
}
void JavaScriptFrame::GetFunctions(List<JSFunction*>* functions) const {
void JavaScriptFrame::GetFunctions(List<SharedFunctionInfo*>* functions) const {
DCHECK(functions->length() == 0);
functions->Add(function());
functions->Add(function()->shared());
}
void JavaScriptFrame::Summarize(List<FrameSummary>* functions,
......@@ -1474,7 +1473,7 @@ Object* OptimizedFrame::receiver() const {
}
}
void OptimizedFrame::GetFunctions(List<JSFunction*>* functions) const {
void OptimizedFrame::GetFunctions(List<SharedFunctionInfo*>* functions) const {
DCHECK(functions->length() == 0);
DCHECK(is_optimized());
......@@ -1504,25 +1503,20 @@ void OptimizedFrame::GetFunctions(List<JSFunction*>* functions) const {
// in the deoptimization translation are ordered bottom-to-top.
while (jsframe_count != 0) {
opcode = static_cast<Translation::Opcode>(it.Next());
// Skip over operands to advance to the next opcode.
it.Skip(Translation::NumberOfOperandsFor(opcode));
if (opcode == Translation::JS_FRAME ||
opcode == Translation::INTERPRETED_FRAME) {
it.Next(); // Skip bailout id.
jsframe_count--;
// The translation commands are ordered and the function is always at the
// first position.
opcode = static_cast<Translation::Opcode>(it.Next());
// The second operand of the frame points to the function.
Object* shared = literal_array->get(it.Next());
functions->Add(SharedFunctionInfo::cast(shared));
// Get the correct function in the optimized frame.
Object* function;
if (opcode == Translation::LITERAL) {
function = literal_array->get(it.Next());
} else {
CHECK_EQ(Translation::STACK_SLOT, opcode);
function = StackSlotAt(it.Next());
}
functions->Add(JSFunction::cast(function));
// Skip over remaining operands to advance to the next opcode.
it.Skip(Translation::NumberOfOperandsFor(opcode) - 2);
} else {
// Skip over operands to advance to the next opcode.
it.Skip(Translation::NumberOfOperandsFor(opcode));
}
}
}
......
......@@ -1025,8 +1025,8 @@ class JavaScriptFrame : public StandardFrame {
// Determine the code for the frame.
Code* unchecked_code() const override;
// Return a list with JSFunctions of this frame.
virtual void GetFunctions(List<JSFunction*>* functions) const;
// Return a list with {SharedFunctionInfo} objects of this frame.
virtual void GetFunctions(List<SharedFunctionInfo*>* functions) const;
// Lookup exception handler for current {pc}, returns -1 if none found. Also
// returns data associated with the handler site specific to the frame type:
......@@ -1105,10 +1105,10 @@ class OptimizedFrame : public JavaScriptFrame {
// GC support.
void Iterate(ObjectVisitor* v) const override;
// Return a list with JSFunctions of this frame.
// Return a list with {SharedFunctionInfo} objects of this frame.
// The functions are ordered bottom-to-top (i.e. functions.last()
// is the top-most activation)
void GetFunctions(List<JSFunction*>* functions) const override;
void GetFunctions(List<SharedFunctionInfo*>* functions) const override;
void Summarize(
List<FrameSummary>* frames,
......
......@@ -464,10 +464,10 @@ void RuntimeProfiler::MarkCandidatesForOptimization() {
// Update shared function info ticks after checking for whether functions
// should be optimized to keep FCG (which updates ticks on code) and
// Ignition (which updates ticks on shared function info) in sync.
List<JSFunction*> functions(4);
List<SharedFunctionInfo*> functions(4);
frame->GetFunctions(&functions);
for (int i = functions.length(); --i >= 0;) {
SharedFunctionInfo* shared_function_info = functions[i]->shared();
SharedFunctionInfo* shared_function_info = functions[i];
int ticks = shared_function_info->profiler_ticks();
if (ticks < Smi::kMaxValue) {
shared_function_info->set_profiler_ticks(ticks + 1);
......
......@@ -353,7 +353,7 @@ std::unique_ptr<Handle<Object>[]> GetCallerArguments(Isolate* isolate,
// Find frame containing arguments passed to the caller.
JavaScriptFrameIterator it(isolate);
JavaScriptFrame* frame = it.frame();
List<JSFunction*> functions(2);
List<SharedFunctionInfo*> functions(2);
frame->GetFunctions(&functions);
if (functions.length() > 1) {
int inlined_jsframe_index = functions.length() - 1;
......
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