Commit 91e2bf6e authored by yangguo's avatar yangguo Committed by Commit bot

Make global eval faster by lazily computing its call position.

Prior to 89d7bfda we always just collected the code offset and computed the
source position lazily. However, for local eval we already have the source
position ready, so we can just store that. For global eval we still have to
compute from the code offset. This CL changes the computation to be done only
on demand.

R=mstarzinger@chromium.org
BUG=chromium:604646
LOG=N

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

Cr-Commit-Position: refs/heads/master@{#35630}
parent 7fa7bfac
......@@ -668,8 +668,7 @@ void Accessors::ScriptEvalFromScriptPositionGetter(
Script::cast(Handle<JSValue>::cast(object)->value()), isolate);
Handle<Object> result = isolate->factory()->undefined_value();
if (script->compilation_type() == Script::COMPILATION_TYPE_EVAL) {
result =
Handle<Object>(Smi::FromInt(script->eval_from_position()), isolate);
result = Handle<Object>(Smi::FromInt(script->GetEvalPosition()), isolate);
}
info.GetReturnValue().Set(Utils::ToLocal(result));
}
......
......@@ -2067,19 +2067,9 @@ MaybeHandle<JSFunction> CompileString(Handle<Context> context,
}
// Compile source string in the native context.
StackTraceFrameIterator it(isolate);
int eval_scope_position = 0;
int eval_position = RelocInfo::kNoPosition;
Handle<SharedFunctionInfo> outer_info;
if (!it.done() && it.is_javascript()) {
FrameSummary summary = FrameSummary::GetFirst(it.javascript_frame());
eval_position =
summary.abstract_code()->SourcePosition(summary.code_offset());
outer_info = Handle<SharedFunctionInfo>(summary.function()->shared());
} else {
outer_info =
Handle<SharedFunctionInfo>(native_context->closure()->shared());
}
Handle<SharedFunctionInfo> outer_info(native_context->closure()->shared());
return Compiler::GetFunctionFromEval(source, outer_info, native_context,
SLOPPY, restriction, eval_scope_position,
eval_position);
......
......@@ -1254,8 +1254,7 @@ MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
}
script->set_origin_options(options);
script->set_compilation_type(Script::COMPILATION_TYPE_EVAL);
script->set_eval_from_shared(*outer_info);
script->set_eval_from_position(eval_position);
Script::SetEvalOrigin(script, outer_info, eval_position);
Zone zone(isolate->allocator());
ParseInfo parse_info(&zone, script);
......
......@@ -12,9 +12,9 @@
#include "src/accessors.h"
#include "src/allocation-site-scopes.h"
#include "src/api.h"
#include "src/api-arguments.h"
#include "src/api-natives.h"
#include "src/api.h"
#include "src/base/bits.h"
#include "src/base/utils/random-number-generator.h"
#include "src/bootstrapper.h"
......@@ -30,6 +30,7 @@
#include "src/field-index-inl.h"
#include "src/field-index.h"
#include "src/field-type.h"
#include "src/frames-inl.h"
#include "src/full-codegen/full-codegen.h"
#include "src/ic/ic.h"
#include "src/identity-map.h"
......@@ -12997,6 +12998,45 @@ void Oddball::Initialize(Isolate* isolate, Handle<Oddball> oddball,
oddball->set_kind(kind);
}
void Script::SetEvalOrigin(Handle<Script> script,
Handle<SharedFunctionInfo> outer_info,
int eval_position) {
if (eval_position == RelocInfo::kNoPosition) {
// If the position is missing, attempt to get the code offset from the
// current activation. Do not translate the code offset into source
// position, but store it as negative value for lazy translation.
StackTraceFrameIterator it(script->GetIsolate());
if (!it.done() && it.is_javascript()) {
FrameSummary summary = FrameSummary::GetFirst(it.javascript_frame());
script->set_eval_from_shared(summary.function()->shared());
script->set_eval_from_position(-summary.code_offset());
return;
}
eval_position = 0;
}
script->set_eval_from_shared(*outer_info);
script->set_eval_from_position(eval_position);
}
int Script::GetEvalPosition() {
DisallowHeapAllocation no_gc;
DCHECK(compilation_type() == Script::COMPILATION_TYPE_EVAL);
int position = eval_from_position();
if (position < 0) {
// Due to laziness, the position may not have been translated from code
// offset yet, which would be encoded as negative integer. In that case,
// translate and set the position.
if (eval_from_shared()->IsUndefined()) {
position = 0;
} else {
SharedFunctionInfo* shared = SharedFunctionInfo::cast(eval_from_shared());
position = shared->abstract_code()->SourcePosition(-position);
}
DCHECK(position >= 0);
set_eval_from_position(position);
}
return position;
}
void Script::InitLineEnds(Handle<Script> script) {
if (!script->line_ends()->IsUndefined()) return;
......
......@@ -6435,8 +6435,9 @@ class Script: public Struct {
// function from which eval was called.
DECL_ACCESSORS(eval_from_shared, Object)
// [eval_from_position]: the source position in the code for the
// function from which eval was called.
// [eval_from_position]: the source position in the code for the function
// from which eval was called, as positive integer. Or the code offset in the
// code from which eval was called, as negative integer.
DECL_INT_ACCESSORS(eval_from_position)
// [shared_function_infos]: weak fixed array containing all shared
......@@ -6489,6 +6490,13 @@ class Script: public Struct {
static Handle<Object> GetNameOrSourceURL(Handle<Script> script);
// Set eval origin for stack trace formatting.
static void SetEvalOrigin(Handle<Script> script,
Handle<SharedFunctionInfo> outer,
int eval_position);
// Retrieve source position from where eval was called.
int GetEvalPosition();
// Init line_ends array with source code positions of line ends.
static void InitLineEnds(Handle<Script> script);
......
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