Use shared function info for eval cache key.
R=verwaest@chromium.org Review URL: https://codereview.chromium.org/678843004 Cr-Commit-Position: refs/heads/master@{#24927} git-svn-id: https://v8.googlecode.com/svn/branches/bleeding_edge@24927 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
ef1ca7a2ed
commit
0dfbf83468
@ -2944,13 +2944,16 @@ void FullCodeGenerator::EmitCall(Call* expr, CallICState::CallType call_type) {
|
||||
|
||||
|
||||
void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
||||
// r4: copy of the first argument or undefined if it doesn't exist.
|
||||
// r5: copy of the first argument or undefined if it doesn't exist.
|
||||
if (arg_count > 0) {
|
||||
__ ldr(r4, MemOperand(sp, arg_count * kPointerSize));
|
||||
__ ldr(r5, MemOperand(sp, arg_count * kPointerSize));
|
||||
} else {
|
||||
__ LoadRoot(r4, Heap::kUndefinedValueRootIndex);
|
||||
__ LoadRoot(r5, Heap::kUndefinedValueRootIndex);
|
||||
}
|
||||
|
||||
// r4: the receiver of the enclosing function.
|
||||
__ ldr(r4, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
|
||||
|
||||
// r3: the receiver of the enclosing function.
|
||||
int receiver_offset = 2 + info_->scope()->num_parameters();
|
||||
__ ldr(r3, MemOperand(fp, receiver_offset * kPointerSize));
|
||||
@ -2962,8 +2965,9 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
||||
__ mov(r1, Operand(Smi::FromInt(scope()->start_position())));
|
||||
|
||||
// Do the runtime call.
|
||||
__ Push(r5);
|
||||
__ Push(r4, r3, r2, r1);
|
||||
__ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
|
||||
__ CallRuntime(Runtime::kResolvePossiblyDirectEval, 6);
|
||||
}
|
||||
|
||||
|
||||
|
@ -2609,11 +2609,12 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
||||
// Prepare to push a copy of the first argument or undefined if it doesn't
|
||||
// exist.
|
||||
if (arg_count > 0) {
|
||||
__ Peek(x10, arg_count * kXRegSize);
|
||||
__ Peek(x9, arg_count * kXRegSize);
|
||||
} else {
|
||||
__ LoadRoot(x10, Heap::kUndefinedValueRootIndex);
|
||||
__ LoadRoot(x9, Heap::kUndefinedValueRootIndex);
|
||||
}
|
||||
|
||||
__ Ldr(x10, MemOperand(fp, JavaScriptFrameConstants::kFunctionOffset));
|
||||
// Prepare to push the receiver of the enclosing function.
|
||||
int receiver_offset = 2 + info_->scope()->num_parameters();
|
||||
__ Ldr(x11, MemOperand(fp, receiver_offset * kPointerSize));
|
||||
@ -2624,10 +2625,10 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
||||
__ Mov(x13, Smi::FromInt(scope()->start_position()));
|
||||
|
||||
// Push.
|
||||
__ Push(x10, x11, x12, x13);
|
||||
__ Push(x9, x10, x11, x12, x13);
|
||||
|
||||
// Do the runtime call.
|
||||
__ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
|
||||
__ CallRuntime(Runtime::kResolvePossiblyDirectEval, 6);
|
||||
}
|
||||
|
||||
|
||||
|
@ -221,10 +221,8 @@ void CompilationCacheScript::Put(Handle<String> source,
|
||||
|
||||
|
||||
MaybeHandle<SharedFunctionInfo> CompilationCacheEval::Lookup(
|
||||
Handle<String> source,
|
||||
Handle<Context> context,
|
||||
StrictMode strict_mode,
|
||||
int scope_position) {
|
||||
Handle<String> source, Handle<SharedFunctionInfo> outer_info,
|
||||
StrictMode strict_mode, int scope_position) {
|
||||
HandleScope scope(isolate());
|
||||
// Make sure not to leak the table into the surrounding handle
|
||||
// scope. Otherwise, we risk keeping old tables around even after
|
||||
@ -233,14 +231,14 @@ MaybeHandle<SharedFunctionInfo> CompilationCacheEval::Lookup(
|
||||
int generation;
|
||||
for (generation = 0; generation < generations(); generation++) {
|
||||
Handle<CompilationCacheTable> table = GetTable(generation);
|
||||
result = table->LookupEval(source, context, strict_mode, scope_position);
|
||||
result = table->LookupEval(source, outer_info, strict_mode, scope_position);
|
||||
if (result->IsSharedFunctionInfo()) break;
|
||||
}
|
||||
if (result->IsSharedFunctionInfo()) {
|
||||
Handle<SharedFunctionInfo> function_info =
|
||||
Handle<SharedFunctionInfo>::cast(result);
|
||||
if (generation != 0) {
|
||||
Put(source, context, function_info, scope_position);
|
||||
Put(source, outer_info, function_info, scope_position);
|
||||
}
|
||||
isolate()->counters()->compilation_cache_hits()->Increment();
|
||||
return scope.CloseAndEscape(function_info);
|
||||
@ -252,12 +250,12 @@ MaybeHandle<SharedFunctionInfo> CompilationCacheEval::Lookup(
|
||||
|
||||
|
||||
void CompilationCacheEval::Put(Handle<String> source,
|
||||
Handle<Context> context,
|
||||
Handle<SharedFunctionInfo> outer_info,
|
||||
Handle<SharedFunctionInfo> function_info,
|
||||
int scope_position) {
|
||||
HandleScope scope(isolate());
|
||||
Handle<CompilationCacheTable> table = GetFirstTable();
|
||||
table = CompilationCacheTable::PutEval(table, source, context,
|
||||
table = CompilationCacheTable::PutEval(table, source, outer_info,
|
||||
function_info, scope_position);
|
||||
SetFirstTable(table);
|
||||
}
|
||||
@ -324,20 +322,18 @@ MaybeHandle<SharedFunctionInfo> CompilationCache::LookupScript(
|
||||
|
||||
|
||||
MaybeHandle<SharedFunctionInfo> CompilationCache::LookupEval(
|
||||
Handle<String> source,
|
||||
Handle<Context> context,
|
||||
StrictMode strict_mode,
|
||||
int scope_position) {
|
||||
Handle<String> source, Handle<SharedFunctionInfo> outer_info,
|
||||
Handle<Context> context, StrictMode strict_mode, int scope_position) {
|
||||
if (!IsEnabled()) return MaybeHandle<SharedFunctionInfo>();
|
||||
|
||||
MaybeHandle<SharedFunctionInfo> result;
|
||||
if (context->IsNativeContext()) {
|
||||
result = eval_global_.Lookup(
|
||||
source, context, strict_mode, scope_position);
|
||||
result =
|
||||
eval_global_.Lookup(source, outer_info, strict_mode, scope_position);
|
||||
} else {
|
||||
DCHECK(scope_position != RelocInfo::kNoPosition);
|
||||
result = eval_contextual_.Lookup(
|
||||
source, context, strict_mode, scope_position);
|
||||
result = eval_contextual_.Lookup(source, outer_info, strict_mode,
|
||||
scope_position);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
@ -361,6 +357,7 @@ void CompilationCache::PutScript(Handle<String> source,
|
||||
|
||||
|
||||
void CompilationCache::PutEval(Handle<String> source,
|
||||
Handle<SharedFunctionInfo> outer_info,
|
||||
Handle<Context> context,
|
||||
Handle<SharedFunctionInfo> function_info,
|
||||
int scope_position) {
|
||||
@ -368,10 +365,10 @@ void CompilationCache::PutEval(Handle<String> source,
|
||||
|
||||
HandleScope scope(isolate());
|
||||
if (context->IsNativeContext()) {
|
||||
eval_global_.Put(source, context, function_info, scope_position);
|
||||
eval_global_.Put(source, outer_info, function_info, scope_position);
|
||||
} else {
|
||||
DCHECK(scope_position != RelocInfo::kNoPosition);
|
||||
eval_contextual_.Put(source, context, function_info, scope_position);
|
||||
eval_contextual_.Put(source, outer_info, function_info, scope_position);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -114,14 +114,12 @@ class CompilationCacheEval: public CompilationSubCache {
|
||||
: CompilationSubCache(isolate, generations) { }
|
||||
|
||||
MaybeHandle<SharedFunctionInfo> Lookup(Handle<String> source,
|
||||
Handle<Context> context,
|
||||
Handle<SharedFunctionInfo> outer_info,
|
||||
StrictMode strict_mode,
|
||||
int scope_position);
|
||||
|
||||
void Put(Handle<String> source,
|
||||
Handle<Context> context,
|
||||
Handle<SharedFunctionInfo> function_info,
|
||||
int scope_position);
|
||||
void Put(Handle<String> source, Handle<SharedFunctionInfo> outer_info,
|
||||
Handle<SharedFunctionInfo> function_info, int scope_position);
|
||||
|
||||
private:
|
||||
DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheEval);
|
||||
@ -161,8 +159,8 @@ class CompilationCache {
|
||||
// given context. Returns an empty handle if the cache doesn't
|
||||
// contain a script for the given source string.
|
||||
MaybeHandle<SharedFunctionInfo> LookupEval(
|
||||
Handle<String> source, Handle<Context> context, StrictMode strict_mode,
|
||||
int scope_position);
|
||||
Handle<String> source, Handle<SharedFunctionInfo> outer_info,
|
||||
Handle<Context> context, StrictMode strict_mode, int scope_position);
|
||||
|
||||
// Returns the regexp data associated with the given regexp if it
|
||||
// is in cache, otherwise an empty handle.
|
||||
@ -177,10 +175,9 @@ class CompilationCache {
|
||||
|
||||
// Associate the (source, context->closure()->shared(), kind) triple
|
||||
// with the shared function info. This may overwrite an existing mapping.
|
||||
void PutEval(Handle<String> source,
|
||||
void PutEval(Handle<String> source, Handle<SharedFunctionInfo> outer_info,
|
||||
Handle<Context> context,
|
||||
Handle<SharedFunctionInfo> function_info,
|
||||
int scope_position);
|
||||
Handle<SharedFunctionInfo> function_info, int scope_position);
|
||||
|
||||
// Associate the (source, flags) pair to the given regexp data.
|
||||
// This may overwrite an existing mapping.
|
||||
|
@ -1096,11 +1096,9 @@ static Handle<SharedFunctionInfo> CompileToplevel(CompilationInfo* info) {
|
||||
|
||||
|
||||
MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
|
||||
Handle<String> source,
|
||||
Handle<Context> context,
|
||||
StrictMode strict_mode,
|
||||
ParseRestriction restriction,
|
||||
int scope_position) {
|
||||
Handle<String> source, Handle<SharedFunctionInfo> outer_info,
|
||||
Handle<Context> context, StrictMode strict_mode,
|
||||
ParseRestriction restriction, int scope_position) {
|
||||
Isolate* isolate = source->GetIsolate();
|
||||
int source_length = source->length();
|
||||
isolate->counters()->total_eval_size()->Increment(source_length);
|
||||
@ -1108,7 +1106,7 @@ MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
|
||||
|
||||
CompilationCache* compilation_cache = isolate->compilation_cache();
|
||||
MaybeHandle<SharedFunctionInfo> maybe_shared_info =
|
||||
compilation_cache->LookupEval(source, context, strict_mode,
|
||||
compilation_cache->LookupEval(source, outer_info, context, strict_mode,
|
||||
scope_position);
|
||||
Handle<SharedFunctionInfo> shared_info;
|
||||
|
||||
@ -1135,8 +1133,8 @@ MaybeHandle<JSFunction> Compiler::GetFunctionFromEval(
|
||||
// If caller is strict mode, the result must be in strict mode as well.
|
||||
DCHECK(strict_mode == SLOPPY || shared_info->strict_mode() == STRICT);
|
||||
if (!shared_info->dont_cache()) {
|
||||
compilation_cache->PutEval(
|
||||
source, context, shared_info, scope_position);
|
||||
compilation_cache->PutEval(source, outer_info, context, shared_info,
|
||||
scope_position);
|
||||
}
|
||||
}
|
||||
} else if (shared_info->ic_age() != isolate->heap()->global_ic_age()) {
|
||||
|
@ -684,11 +684,9 @@ class Compiler : public AllStatic {
|
||||
|
||||
// Compile a String source within a context for eval.
|
||||
MUST_USE_RESULT static MaybeHandle<JSFunction> GetFunctionFromEval(
|
||||
Handle<String> source,
|
||||
Handle<Context> context,
|
||||
StrictMode strict_mode,
|
||||
ParseRestriction restriction,
|
||||
int scope_position);
|
||||
Handle<String> source, Handle<SharedFunctionInfo> outer_info,
|
||||
Handle<Context> context, StrictMode strict_mode,
|
||||
ParseRestriction restriction, int scope_position);
|
||||
|
||||
// Compile a String source within a context.
|
||||
static Handle<SharedFunctionInfo> CompileScript(
|
||||
|
@ -1308,12 +1308,14 @@ void AstGraphBuilder::VisitCall(Call* expr) {
|
||||
|
||||
// Create node to ask for help resolving potential eval call. This will
|
||||
// provide a fully resolved callee and the corresponding receiver.
|
||||
Node* function = GetFunctionClosure();
|
||||
Node* receiver = environment()->Lookup(info()->scope()->receiver());
|
||||
Node* strict = jsgraph()->Constant(strict_mode());
|
||||
Node* position = jsgraph()->Constant(info()->scope()->start_position());
|
||||
const Operator* op =
|
||||
javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
|
||||
Node* pair = NewNode(op, callee, source, receiver, strict, position);
|
||||
javascript()->CallRuntime(Runtime::kResolvePossiblyDirectEval, 6);
|
||||
Node* pair =
|
||||
NewNode(op, callee, source, function, receiver, strict, position);
|
||||
PrepareFrameState(pair, expr->EvalOrLookupId(),
|
||||
OutputFrameStateCombine::PokeAt(arg_count + 1));
|
||||
Node* new_callee = NewNode(common()->Projection(0), pair);
|
||||
|
@ -2857,6 +2857,8 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
||||
__ push(Immediate(isolate()->factory()->undefined_value()));
|
||||
}
|
||||
|
||||
// Push the enclosing function.
|
||||
__ push(Operand(ebp, JavaScriptFrameConstants::kFunctionOffset));
|
||||
// Push the receiver of the enclosing function.
|
||||
__ push(Operand(ebp, (2 + info_->scope()->num_parameters()) * kPointerSize));
|
||||
// Push the language mode.
|
||||
@ -2866,7 +2868,7 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
||||
__ push(Immediate(Smi::FromInt(scope()->start_position())));
|
||||
|
||||
// Do the runtime call.
|
||||
__ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
|
||||
__ CallRuntime(Runtime::kResolvePossiblyDirectEval, 6);
|
||||
}
|
||||
|
||||
|
||||
|
@ -14845,13 +14845,13 @@ Handle<Object> CompilationCacheTable::Lookup(Handle<String> src,
|
||||
}
|
||||
|
||||
|
||||
Handle<Object> CompilationCacheTable::LookupEval(Handle<String> src,
|
||||
Handle<Context> context,
|
||||
StrictMode strict_mode,
|
||||
int scope_position) {
|
||||
Handle<Object> CompilationCacheTable::LookupEval(
|
||||
Handle<String> src, Handle<SharedFunctionInfo> outer_info,
|
||||
StrictMode strict_mode, int scope_position) {
|
||||
Isolate* isolate = GetIsolate();
|
||||
Handle<SharedFunctionInfo> shared(context->closure()->shared());
|
||||
StringSharedKey key(src, shared, strict_mode, scope_position);
|
||||
// Cache key is the tuple (source, outer shared function info, scope position)
|
||||
// to unambiguously identify the context chain the cached eval code assumes.
|
||||
StringSharedKey key(src, outer_info, strict_mode, scope_position);
|
||||
int entry = FindEntry(&key);
|
||||
if (entry == kNotFound) return isolate->factory()->undefined_value();
|
||||
return Handle<Object>(get(EntryToIndex(entry) + 1), isolate);
|
||||
@ -14888,11 +14888,10 @@ Handle<CompilationCacheTable> CompilationCacheTable::Put(
|
||||
|
||||
Handle<CompilationCacheTable> CompilationCacheTable::PutEval(
|
||||
Handle<CompilationCacheTable> cache, Handle<String> src,
|
||||
Handle<Context> context, Handle<SharedFunctionInfo> value,
|
||||
Handle<SharedFunctionInfo> outer_info, Handle<SharedFunctionInfo> value,
|
||||
int scope_position) {
|
||||
Isolate* isolate = cache->GetIsolate();
|
||||
Handle<SharedFunctionInfo> shared(context->closure()->shared());
|
||||
StringSharedKey key(src, shared, value->strict_mode(), scope_position);
|
||||
StringSharedKey key(src, outer_info, value->strict_mode(), scope_position);
|
||||
cache = EnsureCapacity(cache, 1, &key);
|
||||
Handle<Object> k = key.AsHandle(isolate);
|
||||
int entry = cache->FindInsertionEntry(key.Hash());
|
||||
|
@ -7943,15 +7943,16 @@ class CompilationCacheTable: public HashTable<CompilationCacheTable,
|
||||
public:
|
||||
// Find cached value for a string key, otherwise return null.
|
||||
Handle<Object> Lookup(Handle<String> src, Handle<Context> context);
|
||||
Handle<Object> LookupEval(Handle<String> src, Handle<Context> context,
|
||||
StrictMode strict_mode, int scope_position);
|
||||
Handle<Object> LookupEval(Handle<String> src,
|
||||
Handle<SharedFunctionInfo> shared,
|
||||
StrictMode strict_mode, int scope_position);
|
||||
Handle<Object> LookupRegExp(Handle<String> source, JSRegExp::Flags flags);
|
||||
static Handle<CompilationCacheTable> Put(
|
||||
Handle<CompilationCacheTable> cache, Handle<String> src,
|
||||
Handle<Context> context, Handle<Object> value);
|
||||
static Handle<CompilationCacheTable> PutEval(
|
||||
Handle<CompilationCacheTable> cache, Handle<String> src,
|
||||
Handle<Context> context, Handle<SharedFunctionInfo> value,
|
||||
Handle<SharedFunctionInfo> context, Handle<SharedFunctionInfo> value,
|
||||
int scope_position);
|
||||
static Handle<CompilationCacheTable> PutRegExp(
|
||||
Handle<CompilationCacheTable> cache, Handle<String> src,
|
||||
|
@ -369,16 +369,18 @@ RUNTIME_FUNCTION(Runtime_CompileString) {
|
||||
ParseRestriction restriction = function_literal_only
|
||||
? ONLY_SINGLE_FUNCTION_LITERAL
|
||||
: NO_PARSE_RESTRICTION;
|
||||
Handle<SharedFunctionInfo> outer_info(context->closure()->shared(), isolate);
|
||||
Handle<JSFunction> fun;
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
||||
isolate, fun,
|
||||
Compiler::GetFunctionFromEval(source, context, SLOPPY, restriction,
|
||||
RelocInfo::kNoPosition));
|
||||
Compiler::GetFunctionFromEval(source, outer_info, context, SLOPPY,
|
||||
restriction, RelocInfo::kNoPosition));
|
||||
return *fun;
|
||||
}
|
||||
|
||||
|
||||
static ObjectPair CompileGlobalEval(Isolate* isolate, Handle<String> source,
|
||||
Handle<SharedFunctionInfo> outer_info,
|
||||
Handle<Object> receiver,
|
||||
StrictMode strict_mode,
|
||||
int scope_position) {
|
||||
@ -404,8 +406,8 @@ static ObjectPair CompileGlobalEval(Isolate* isolate, Handle<String> source,
|
||||
Handle<JSFunction> compiled;
|
||||
ASSIGN_RETURN_ON_EXCEPTION_VALUE(
|
||||
isolate, compiled,
|
||||
Compiler::GetFunctionFromEval(source, context, strict_mode, restriction,
|
||||
scope_position),
|
||||
Compiler::GetFunctionFromEval(source, outer_info, context, strict_mode,
|
||||
restriction, scope_position),
|
||||
MakePair(isolate->heap()->exception(), NULL));
|
||||
return MakePair(*compiled, *receiver);
|
||||
}
|
||||
@ -413,7 +415,7 @@ static ObjectPair CompileGlobalEval(Isolate* isolate, Handle<String> source,
|
||||
|
||||
RUNTIME_FUNCTION_RETURN_PAIR(Runtime_ResolvePossiblyDirectEval) {
|
||||
HandleScope scope(isolate);
|
||||
DCHECK(args.length() == 5);
|
||||
DCHECK(args.length() == 6);
|
||||
|
||||
Handle<Object> callee = args.at<Object>(0);
|
||||
|
||||
@ -427,12 +429,14 @@ RUNTIME_FUNCTION_RETURN_PAIR(Runtime_ResolvePossiblyDirectEval) {
|
||||
return MakePair(*callee, isolate->heap()->undefined_value());
|
||||
}
|
||||
|
||||
DCHECK(args[3]->IsSmi());
|
||||
DCHECK(args.smi_at(3) == SLOPPY || args.smi_at(3) == STRICT);
|
||||
StrictMode strict_mode = static_cast<StrictMode>(args.smi_at(3));
|
||||
DCHECK(args[4]->IsSmi());
|
||||
return CompileGlobalEval(isolate, args.at<String>(1), args.at<Object>(2),
|
||||
strict_mode, args.smi_at(4));
|
||||
DCHECK(args.smi_at(4) == SLOPPY || args.smi_at(4) == STRICT);
|
||||
StrictMode strict_mode = static_cast<StrictMode>(args.smi_at(4));
|
||||
DCHECK(args[5]->IsSmi());
|
||||
Handle<SharedFunctionInfo> outer_info(args.at<JSFunction>(2)->shared(),
|
||||
isolate);
|
||||
return CompileGlobalEval(isolate, args.at<String>(1), outer_info,
|
||||
args.at<Object>(3), strict_mode, args.smi_at(5));
|
||||
}
|
||||
}
|
||||
} // namespace v8::internal
|
||||
|
@ -2043,6 +2043,7 @@ MUST_USE_RESULT static MaybeHandle<JSObject> MaterializeArgumentsObject(
|
||||
|
||||
// Compile and evaluate source for the given context.
|
||||
static MaybeHandle<Object> DebugEvaluate(Isolate* isolate,
|
||||
Handle<SharedFunctionInfo> outer_info,
|
||||
Handle<Context> context,
|
||||
Handle<Object> context_extension,
|
||||
Handle<Object> receiver,
|
||||
@ -2054,11 +2055,11 @@ static MaybeHandle<Object> DebugEvaluate(Isolate* isolate,
|
||||
}
|
||||
|
||||
Handle<JSFunction> eval_fun;
|
||||
ASSIGN_RETURN_ON_EXCEPTION(
|
||||
isolate, eval_fun, Compiler::GetFunctionFromEval(source, context, SLOPPY,
|
||||
NO_PARSE_RESTRICTION,
|
||||
RelocInfo::kNoPosition),
|
||||
Object);
|
||||
ASSIGN_RETURN_ON_EXCEPTION(isolate, eval_fun,
|
||||
Compiler::GetFunctionFromEval(
|
||||
source, outer_info, context, SLOPPY,
|
||||
NO_PARSE_RESTRICTION, RelocInfo::kNoPosition),
|
||||
Object);
|
||||
|
||||
Handle<Object> result;
|
||||
ASSIGN_RETURN_ON_EXCEPTION(
|
||||
@ -2118,6 +2119,7 @@ RUNTIME_FUNCTION(Runtime_DebugEvaluate) {
|
||||
JavaScriptFrame* frame = it.frame();
|
||||
FrameInspector frame_inspector(frame, inlined_jsframe_index, isolate);
|
||||
Handle<JSFunction> function(JSFunction::cast(frame_inspector.GetFunction()));
|
||||
Handle<SharedFunctionInfo> outer_info(function->shared());
|
||||
|
||||
// Traverse the saved contexts chain to find the active context for the
|
||||
// selected frame.
|
||||
@ -2177,8 +2179,8 @@ RUNTIME_FUNCTION(Runtime_DebugEvaluate) {
|
||||
}
|
||||
|
||||
Handle<Object> receiver(frame->receiver(), isolate);
|
||||
MaybeHandle<Object> maybe_result =
|
||||
DebugEvaluate(isolate, eval_context, context_extension, receiver, source);
|
||||
MaybeHandle<Object> maybe_result = DebugEvaluate(
|
||||
isolate, outer_info, eval_context, context_extension, receiver, source);
|
||||
|
||||
// Remove with-context if it was inserted in between.
|
||||
if (!inner_context.is_null()) inner_context->set_previous(*function_context);
|
||||
@ -2224,10 +2226,11 @@ RUNTIME_FUNCTION(Runtime_DebugEvaluateGlobal) {
|
||||
// debugger was invoked.
|
||||
Handle<Context> context = isolate->native_context();
|
||||
Handle<JSObject> receiver(context->global_proxy());
|
||||
Handle<SharedFunctionInfo> outer_info(context->closure()->shared(), isolate);
|
||||
Handle<Object> result;
|
||||
ASSIGN_RETURN_FAILURE_ON_EXCEPTION(
|
||||
isolate, result,
|
||||
DebugEvaluate(isolate, context, context_extension, receiver, source));
|
||||
isolate, result, DebugEvaluate(isolate, outer_info, context,
|
||||
context_extension, receiver, source));
|
||||
return *result;
|
||||
}
|
||||
|
||||
|
@ -521,7 +521,7 @@ namespace internal {
|
||||
#define RUNTIME_FUNCTION_LIST_RETURN_PAIR(F) \
|
||||
F(LoadLookupSlot, 2, 2) \
|
||||
F(LoadLookupSlotNoReferenceError, 2, 2) \
|
||||
F(ResolvePossiblyDirectEval, 5, 2) \
|
||||
F(ResolvePossiblyDirectEval, 6, 2) \
|
||||
F(ForInInit, 2, 2) /* TODO(turbofan): Only temporary */ \
|
||||
F(ForInNext, 4, 2) /* TODO(turbofan): Only temporary */
|
||||
|
||||
|
@ -2855,6 +2855,9 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
||||
__ PushRoot(Heap::kUndefinedValueRootIndex);
|
||||
}
|
||||
|
||||
// Push the enclosing function.
|
||||
__ Push(Operand(rbp, JavaScriptFrameConstants::kFunctionOffset));
|
||||
|
||||
// Push the receiver of the enclosing function and do runtime call.
|
||||
StackArgumentsAccessor args(rbp, info_->scope()->num_parameters());
|
||||
__ Push(args.GetReceiverOperand());
|
||||
@ -2866,7 +2869,7 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
|
||||
__ Push(Smi::FromInt(scope()->start_position()));
|
||||
|
||||
// Do the runtime call.
|
||||
__ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
|
||||
__ CallRuntime(Runtime::kResolvePossiblyDirectEval, 6);
|
||||
}
|
||||
|
||||
|
||||
|
19
test/mjsunit/regress/regress-eval-cache.js
Normal file
19
test/mjsunit/regress/regress-eval-cache.js
Normal file
@ -0,0 +1,19 @@
|
||||
// Copyright 2014 the V8 project authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
(function f() {
|
||||
try {
|
||||
throw 1;
|
||||
} catch (e) {
|
||||
var a = 0;
|
||||
var b = 0;
|
||||
var c = 0;
|
||||
var x = 1;
|
||||
var result = eval('eval("x")').toString();
|
||||
assertEquals("1", result);
|
||||
}
|
||||
var x = 2;
|
||||
var result = eval('eval("x")').toString();
|
||||
assertEquals("2", result);
|
||||
})();
|
Loading…
Reference in New Issue
Block a user