Make eval compilation cache calling scope sensitive.

Review URL: http://codereview.chromium.org/8518001

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@9984 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
keuchel@chromium.org 2011-11-14 08:58:47 +00:00
parent 7c209a555f
commit b153dcfebf
12 changed files with 145 additions and 72 deletions

View File

@ -2204,7 +2204,11 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
__ mov(r1, Operand(Smi::FromInt(strict_mode))); __ mov(r1, Operand(Smi::FromInt(strict_mode)));
__ push(r1); __ push(r1);
__ CallRuntime(Runtime::kResolvePossiblyDirectEval, 4); // Push the start position of the scope the calls resides in.
__ mov(r1, Operand(Smi::FromInt(scope()->start_position())));
__ push(r1);
__ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
} }

View File

@ -1,4 +1,4 @@
// Copyright 2008 the V8 project authors. All rights reserved. // Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
// met: // met:
@ -27,6 +27,7 @@
#include "v8.h" #include "v8.h"
#include "assembler.h"
#include "compilation-cache.h" #include "compilation-cache.h"
#include "serialize.h" #include "serialize.h"
@ -250,7 +251,8 @@ void CompilationCacheScript::Put(Handle<String> source,
Handle<SharedFunctionInfo> CompilationCacheEval::Lookup( Handle<SharedFunctionInfo> CompilationCacheEval::Lookup(
Handle<String> source, Handle<String> source,
Handle<Context> context, Handle<Context> context,
StrictModeFlag strict_mode) { StrictModeFlag strict_mode,
int scope_position) {
// Make sure not to leak the table into the surrounding handle // Make sure not to leak the table into the surrounding handle
// scope. Otherwise, we risk keeping old tables around even after // scope. Otherwise, we risk keeping old tables around even after
// having cleared the cache. // having cleared the cache.
@ -259,7 +261,8 @@ Handle<SharedFunctionInfo> CompilationCacheEval::Lookup(
{ HandleScope scope(isolate()); { HandleScope scope(isolate());
for (generation = 0; generation < generations(); generation++) { for (generation = 0; generation < generations(); generation++) {
Handle<CompilationCacheTable> table = GetTable(generation); Handle<CompilationCacheTable> table = GetTable(generation);
result = table->LookupEval(*source, *context, strict_mode); result = table->LookupEval(
*source, *context, strict_mode, scope_position);
if (result->IsSharedFunctionInfo()) { if (result->IsSharedFunctionInfo()) {
break; break;
} }
@ -269,7 +272,7 @@ Handle<SharedFunctionInfo> CompilationCacheEval::Lookup(
Handle<SharedFunctionInfo> Handle<SharedFunctionInfo>
function_info(SharedFunctionInfo::cast(result), isolate()); function_info(SharedFunctionInfo::cast(result), isolate());
if (generation != 0) { if (generation != 0) {
Put(source, context, function_info); Put(source, context, function_info, scope_position);
} }
isolate()->counters()->compilation_cache_hits()->Increment(); isolate()->counters()->compilation_cache_hits()->Increment();
return function_info; return function_info;
@ -283,27 +286,31 @@ Handle<SharedFunctionInfo> CompilationCacheEval::Lookup(
MaybeObject* CompilationCacheEval::TryTablePut( MaybeObject* CompilationCacheEval::TryTablePut(
Handle<String> source, Handle<String> source,
Handle<Context> context, Handle<Context> context,
Handle<SharedFunctionInfo> function_info) { Handle<SharedFunctionInfo> function_info,
int scope_position) {
Handle<CompilationCacheTable> table = GetFirstTable(); Handle<CompilationCacheTable> table = GetFirstTable();
return table->PutEval(*source, *context, *function_info); return table->PutEval(*source, *context, *function_info, scope_position);
} }
Handle<CompilationCacheTable> CompilationCacheEval::TablePut( Handle<CompilationCacheTable> CompilationCacheEval::TablePut(
Handle<String> source, Handle<String> source,
Handle<Context> context, Handle<Context> context,
Handle<SharedFunctionInfo> function_info) { Handle<SharedFunctionInfo> function_info,
int scope_position) {
CALL_HEAP_FUNCTION(isolate(), CALL_HEAP_FUNCTION(isolate(),
TryTablePut(source, context, function_info), TryTablePut(
source, context, function_info, scope_position),
CompilationCacheTable); CompilationCacheTable);
} }
void CompilationCacheEval::Put(Handle<String> source, void CompilationCacheEval::Put(Handle<String> source,
Handle<Context> context, Handle<Context> context,
Handle<SharedFunctionInfo> function_info) { Handle<SharedFunctionInfo> function_info,
int scope_position) {
HandleScope scope(isolate()); HandleScope scope(isolate());
SetFirstTable(TablePut(source, context, function_info)); SetFirstTable(TablePut(source, context, function_info, scope_position));
} }
@ -389,16 +396,19 @@ Handle<SharedFunctionInfo> CompilationCache::LookupEval(
Handle<String> source, Handle<String> source,
Handle<Context> context, Handle<Context> context,
bool is_global, bool is_global,
StrictModeFlag strict_mode) { StrictModeFlag strict_mode,
int scope_position) {
if (!IsEnabled()) { if (!IsEnabled()) {
return Handle<SharedFunctionInfo>::null(); return Handle<SharedFunctionInfo>::null();
} }
Handle<SharedFunctionInfo> result; Handle<SharedFunctionInfo> result;
if (is_global) { if (is_global) {
result = eval_global_.Lookup(source, context, strict_mode); result = eval_global_.Lookup(source, context, strict_mode, scope_position);
} else { } else {
result = eval_contextual_.Lookup(source, context, strict_mode); ASSERT(scope_position != RelocInfo::kNoPosition);
result = eval_contextual_.Lookup(
source, context, strict_mode, scope_position);
} }
return result; return result;
} }
@ -427,16 +437,18 @@ void CompilationCache::PutScript(Handle<String> source,
void CompilationCache::PutEval(Handle<String> source, void CompilationCache::PutEval(Handle<String> source,
Handle<Context> context, Handle<Context> context,
bool is_global, bool is_global,
Handle<SharedFunctionInfo> function_info) { Handle<SharedFunctionInfo> function_info,
int scope_position) {
if (!IsEnabled()) { if (!IsEnabled()) {
return; return;
} }
HandleScope scope(isolate()); HandleScope scope(isolate());
if (is_global) { if (is_global) {
eval_global_.Put(source, context, function_info); eval_global_.Put(source, context, function_info, scope_position);
} else { } else {
eval_contextual_.Put(source, context, function_info); ASSERT(scope_position != RelocInfo::kNoPosition);
eval_contextual_.Put(source, context, function_info, scope_position);
} }
} }

View File

@ -1,4 +1,4 @@
// Copyright 2008 the V8 project authors. All rights reserved. // Copyright 2011 the V8 project authors. All rights reserved.
// Redistribution and use in source and binary forms, with or without // Redistribution and use in source and binary forms, with or without
// modification, are permitted provided that the following conditions are // modification, are permitted provided that the following conditions are
// met: // met:
@ -123,7 +123,19 @@ class CompilationCacheScript : public CompilationSubCache {
}; };
// Sub-cache for eval scripts. // Sub-cache for eval scripts. Two caches for eval are used. One for eval calls
// in global contexts and one for eval calls in other contexts. The cache
// considers the following pieces of information when checking for matching
// entries:
// 1. The source string.
// 2. The shared function info of the calling function.
// 3. Whether the source should be compiled as strict code or as non-strict
// code.
// Note: Currently there are clients of CompileEval that always compile
// non-strict code even if the calling function is a strict mode function.
// More specifically these are the CompileString, DebugEvaluate and
// DebugEvaluateGlobal runtime functions.
// 4. The start position of the calling scope.
class CompilationCacheEval: public CompilationSubCache { class CompilationCacheEval: public CompilationSubCache {
public: public:
CompilationCacheEval(Isolate* isolate, int generations) CompilationCacheEval(Isolate* isolate, int generations)
@ -131,23 +143,27 @@ class CompilationCacheEval: public CompilationSubCache {
Handle<SharedFunctionInfo> Lookup(Handle<String> source, Handle<SharedFunctionInfo> Lookup(Handle<String> source,
Handle<Context> context, Handle<Context> context,
StrictModeFlag strict_mode); StrictModeFlag strict_mode,
int scope_position);
void Put(Handle<String> source, void Put(Handle<String> source,
Handle<Context> context, Handle<Context> context,
Handle<SharedFunctionInfo> function_info); Handle<SharedFunctionInfo> function_info,
int scope_position);
private: private:
MUST_USE_RESULT MaybeObject* TryTablePut( MUST_USE_RESULT MaybeObject* TryTablePut(
Handle<String> source, Handle<String> source,
Handle<Context> context, Handle<Context> context,
Handle<SharedFunctionInfo> function_info); Handle<SharedFunctionInfo> function_info,
int scope_position);
// Note: Returns a new hash table if operation results in expansion. // Note: Returns a new hash table if operation results in expansion.
Handle<CompilationCacheTable> TablePut( Handle<CompilationCacheTable> TablePut(
Handle<String> source, Handle<String> source,
Handle<Context> context, Handle<Context> context,
Handle<SharedFunctionInfo> function_info); Handle<SharedFunctionInfo> function_info,
int scope_position);
DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheEval); DISALLOW_IMPLICIT_CONSTRUCTORS(CompilationCacheEval);
}; };
@ -198,7 +214,8 @@ class CompilationCache {
Handle<SharedFunctionInfo> LookupEval(Handle<String> source, Handle<SharedFunctionInfo> LookupEval(Handle<String> source,
Handle<Context> context, Handle<Context> context,
bool is_global, bool is_global,
StrictModeFlag strict_mode); StrictModeFlag strict_mode,
int scope_position);
// Returns the regexp data associated with the given regexp if it // Returns the regexp data associated with the given regexp if it
// is in cache, otherwise an empty handle. // is in cache, otherwise an empty handle.
@ -215,7 +232,8 @@ class CompilationCache {
void PutEval(Handle<String> source, void PutEval(Handle<String> source,
Handle<Context> context, Handle<Context> context,
bool is_global, bool is_global,
Handle<SharedFunctionInfo> function_info); Handle<SharedFunctionInfo> function_info,
int scope_position);
// Associate the (source, flags) pair to the given regexp data. // Associate the (source, flags) pair to the given regexp data.
// This may overwrite an existing mapping. // This may overwrite an existing mapping.

View File

@ -533,7 +533,8 @@ Handle<SharedFunctionInfo> Compiler::Compile(Handle<String> source,
Handle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source, Handle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source,
Handle<Context> context, Handle<Context> context,
bool is_global, bool is_global,
StrictModeFlag strict_mode) { StrictModeFlag strict_mode,
int scope_position) {
Isolate* isolate = source->GetIsolate(); Isolate* isolate = source->GetIsolate();
int source_length = source->length(); int source_length = source->length();
isolate->counters()->total_eval_size()->Increment(source_length); isolate->counters()->total_eval_size()->Increment(source_length);
@ -549,7 +550,8 @@ Handle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source,
result = compilation_cache->LookupEval(source, result = compilation_cache->LookupEval(source,
context, context,
is_global, is_global,
strict_mode); strict_mode,
scope_position);
if (result.is_null()) { if (result.is_null()) {
// Create a script object describing the script to be compiled. // Create a script object describing the script to be compiled.
@ -561,13 +563,13 @@ Handle<SharedFunctionInfo> Compiler::CompileEval(Handle<String> source,
info.SetCallingContext(context); info.SetCallingContext(context);
result = MakeFunctionInfo(&info); result = MakeFunctionInfo(&info);
if (!result.is_null()) { if (!result.is_null()) {
CompilationCache* compilation_cache = isolate->compilation_cache();
// If caller is strict mode, the result must be strict as well, // If caller is strict mode, the result must be strict as well,
// but not the other way around. Consider: // but not the other way around. Consider:
// eval("'use strict'; ..."); // eval("'use strict'; ...");
// TODO(keuchel): adapt this for extended mode. // TODO(keuchel): adapt this for extended mode.
ASSERT(strict_mode == kNonStrictMode || result->strict_mode()); ASSERT(strict_mode == kNonStrictMode || result->strict_mode());
compilation_cache->PutEval(source, context, is_global, result); compilation_cache->PutEval(
source, context, is_global, result, scope_position);
} }
} }

View File

@ -289,7 +289,8 @@ class Compiler : public AllStatic {
static Handle<SharedFunctionInfo> CompileEval(Handle<String> source, static Handle<SharedFunctionInfo> CompileEval(Handle<String> source,
Handle<Context> context, Handle<Context> context,
bool is_global, bool is_global,
StrictModeFlag strict_mode); StrictModeFlag strict_mode,
int scope_position);
// Compile from function info (used for lazy compilation). Returns true on // Compile from function info (used for lazy compilation). Returns true on
// success and false if the compilation resulted in a stack overflow. // success and false if the compilation resulted in a stack overflow.

View File

@ -2152,7 +2152,10 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
FLAG_harmony_scoping ? kStrictMode : strict_mode_flag(); FLAG_harmony_scoping ? kStrictMode : strict_mode_flag();
__ push(Immediate(Smi::FromInt(strict_mode))); __ push(Immediate(Smi::FromInt(strict_mode)));
__ CallRuntime(Runtime::kResolvePossiblyDirectEval, 4); // Push the start position of the scope the calls resides in.
__ push(Immediate(Smi::FromInt(scope()->start_position())));
__ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
} }

View File

@ -2271,7 +2271,11 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
__ li(a1, Operand(Smi::FromInt(strict_mode))); __ li(a1, Operand(Smi::FromInt(strict_mode)));
__ push(a1); __ push(a1);
__ CallRuntime(Runtime::kResolvePossiblyDirectEval, 4); // Push the start position of the scope the calls resides in.
__ li(a1, Operand(Smi::FromInt(scope()->start_position())));
__ push(a1);
__ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
} }

View File

@ -10298,74 +10298,83 @@ class StringSharedKey : public HashTableKey {
public: public:
StringSharedKey(String* source, StringSharedKey(String* source,
SharedFunctionInfo* shared, SharedFunctionInfo* shared,
StrictModeFlag strict_mode) StrictModeFlag strict_mode,
int scope_position)
: source_(source), : source_(source),
shared_(shared), shared_(shared),
strict_mode_(strict_mode) { } strict_mode_(strict_mode),
scope_position_(scope_position) { }
bool IsMatch(Object* other) { bool IsMatch(Object* other) {
if (!other->IsFixedArray()) return false; if (!other->IsFixedArray()) return false;
FixedArray* pair = FixedArray::cast(other); FixedArray* other_array = FixedArray::cast(other);
SharedFunctionInfo* shared = SharedFunctionInfo::cast(pair->get(0)); SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0));
if (shared != shared_) return false; if (shared != shared_) return false;
int strict_unchecked = Smi::cast(pair->get(2))->value(); int strict_unchecked = Smi::cast(other_array->get(2))->value();
ASSERT(strict_unchecked == kStrictMode || ASSERT(strict_unchecked == kStrictMode ||
strict_unchecked == kNonStrictMode); strict_unchecked == kNonStrictMode);
StrictModeFlag strict_mode = static_cast<StrictModeFlag>(strict_unchecked); StrictModeFlag strict_mode = static_cast<StrictModeFlag>(strict_unchecked);
if (strict_mode != strict_mode_) return false; if (strict_mode != strict_mode_) return false;
String* source = String::cast(pair->get(1)); int scope_position = Smi::cast(other_array->get(3))->value();
if (scope_position != scope_position_) return false;
String* source = String::cast(other_array->get(1));
return source->Equals(source_); return source->Equals(source_);
} }
static uint32_t StringSharedHashHelper(String* source, static uint32_t StringSharedHashHelper(String* source,
SharedFunctionInfo* shared, SharedFunctionInfo* shared,
StrictModeFlag strict_mode) { StrictModeFlag strict_mode,
int scope_position) {
uint32_t hash = source->Hash(); uint32_t hash = source->Hash();
if (shared->HasSourceCode()) { if (shared->HasSourceCode()) {
// Instead of using the SharedFunctionInfo pointer in the hash // Instead of using the SharedFunctionInfo pointer in the hash
// code computation, we use a combination of the hash of the // code computation, we use a combination of the hash of the
// script source code and the start and end positions. We do // script source code and the start position of the calling scope.
// this to ensure that the cache entries can survive garbage // We do this to ensure that the cache entries can survive garbage
// collection. // collection.
Script* script = Script::cast(shared->script()); Script* script = Script::cast(shared->script());
hash ^= String::cast(script->source())->Hash(); hash ^= String::cast(script->source())->Hash();
if (strict_mode == kStrictMode) hash ^= 0x8000; if (strict_mode == kStrictMode) hash ^= 0x8000;
hash += shared->start_position(); hash += scope_position;
} }
return hash; return hash;
} }
uint32_t Hash() { uint32_t Hash() {
return StringSharedHashHelper(source_, shared_, strict_mode_); return StringSharedHashHelper(
source_, shared_, strict_mode_, scope_position_);
} }
uint32_t HashForObject(Object* obj) { uint32_t HashForObject(Object* obj) {
FixedArray* pair = FixedArray::cast(obj); FixedArray* other_array = FixedArray::cast(obj);
SharedFunctionInfo* shared = SharedFunctionInfo::cast(pair->get(0)); SharedFunctionInfo* shared = SharedFunctionInfo::cast(other_array->get(0));
String* source = String::cast(pair->get(1)); String* source = String::cast(other_array->get(1));
int strict_unchecked = Smi::cast(pair->get(2))->value(); int strict_unchecked = Smi::cast(other_array->get(2))->value();
ASSERT(strict_unchecked == kStrictMode || ASSERT(strict_unchecked == kStrictMode ||
strict_unchecked == kNonStrictMode); strict_unchecked == kNonStrictMode);
StrictModeFlag strict_mode = static_cast<StrictModeFlag>(strict_unchecked); StrictModeFlag strict_mode = static_cast<StrictModeFlag>(strict_unchecked);
return StringSharedHashHelper(source, shared, strict_mode); int scope_position = Smi::cast(other_array->get(3))->value();
return StringSharedHashHelper(source, shared, strict_mode, scope_position);
} }
MUST_USE_RESULT MaybeObject* AsObject() { MUST_USE_RESULT MaybeObject* AsObject() {
Object* obj; Object* obj;
{ MaybeObject* maybe_obj = source_->GetHeap()->AllocateFixedArray(3); { MaybeObject* maybe_obj = source_->GetHeap()->AllocateFixedArray(4);
if (!maybe_obj->ToObject(&obj)) return maybe_obj; if (!maybe_obj->ToObject(&obj)) return maybe_obj;
} }
FixedArray* pair = FixedArray::cast(obj); FixedArray* other_array = FixedArray::cast(obj);
pair->set(0, shared_); other_array->set(0, shared_);
pair->set(1, source_); other_array->set(1, source_);
pair->set(2, Smi::FromInt(strict_mode_)); other_array->set(2, Smi::FromInt(strict_mode_));
return pair; other_array->set(3, Smi::FromInt(scope_position_));
return other_array;
} }
private: private:
String* source_; String* source_;
SharedFunctionInfo* shared_; SharedFunctionInfo* shared_;
StrictModeFlag strict_mode_; StrictModeFlag strict_mode_;
int scope_position_;
}; };
@ -11520,8 +11529,12 @@ Object* CompilationCacheTable::Lookup(String* src) {
Object* CompilationCacheTable::LookupEval(String* src, Object* CompilationCacheTable::LookupEval(String* src,
Context* context, Context* context,
StrictModeFlag strict_mode) { StrictModeFlag strict_mode,
StringSharedKey key(src, context->closure()->shared(), strict_mode); int scope_position) {
StringSharedKey key(src,
context->closure()->shared(),
strict_mode,
scope_position);
int entry = FindEntry(&key); int entry = FindEntry(&key);
if (entry == kNotFound) return GetHeap()->undefined_value(); if (entry == kNotFound) return GetHeap()->undefined_value();
return get(EntryToIndex(entry) + 1); return get(EntryToIndex(entry) + 1);
@ -11556,10 +11569,12 @@ MaybeObject* CompilationCacheTable::Put(String* src, Object* value) {
MaybeObject* CompilationCacheTable::PutEval(String* src, MaybeObject* CompilationCacheTable::PutEval(String* src,
Context* context, Context* context,
SharedFunctionInfo* value) { SharedFunctionInfo* value,
int scope_position) {
StringSharedKey key(src, StringSharedKey key(src,
context->closure()->shared(), context->closure()->shared(),
value->strict_mode_flag()); value->strict_mode_flag(),
scope_position);
Object* obj; Object* obj;
{ MaybeObject* maybe_obj = EnsureCapacity(1, &key); { MaybeObject* maybe_obj = EnsureCapacity(1, &key);
if (!maybe_obj->ToObject(&obj)) return maybe_obj; if (!maybe_obj->ToObject(&obj)) return maybe_obj;

View File

@ -5849,12 +5849,16 @@ class CompilationCacheTable: public HashTable<CompilationCacheShape,
public: public:
// Find cached value for a string key, otherwise return null. // Find cached value for a string key, otherwise return null.
Object* Lookup(String* src); Object* Lookup(String* src);
Object* LookupEval(String* src, Context* context, StrictModeFlag strict_mode); Object* LookupEval(String* src,
Context* context,
StrictModeFlag strict_mode,
int scope_position);
Object* LookupRegExp(String* source, JSRegExp::Flags flags); Object* LookupRegExp(String* source, JSRegExp::Flags flags);
MaybeObject* Put(String* src, Object* value); MaybeObject* Put(String* src, Object* value);
MaybeObject* PutEval(String* src, MaybeObject* PutEval(String* src,
Context* context, Context* context,
SharedFunctionInfo* value); SharedFunctionInfo* value,
int scope_position);
MaybeObject* PutRegExp(String* src, JSRegExp::Flags flags, FixedArray* value); MaybeObject* PutRegExp(String* src, JSRegExp::Flags flags, FixedArray* value);
// Remove given value from cache. // Remove given value from cache.

View File

@ -9477,10 +9477,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileString) {
} }
// Compile source string in the global context. // Compile source string in the global context.
Handle<SharedFunctionInfo> shared = Compiler::CompileEval(source, Handle<SharedFunctionInfo> shared = Compiler::CompileEval(
context, source, context, true, kNonStrictMode, RelocInfo::kNoPosition);
true,
kNonStrictMode);
if (shared.is_null()) return Failure::Exception(); if (shared.is_null()) return Failure::Exception();
Handle<JSFunction> fun = Handle<JSFunction> fun =
isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, isolate->factory()->NewFunctionFromSharedFunctionInfo(shared,
@ -9493,7 +9491,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_CompileString) {
static ObjectPair CompileGlobalEval(Isolate* isolate, static ObjectPair CompileGlobalEval(Isolate* isolate,
Handle<String> source, Handle<String> source,
Handle<Object> receiver, Handle<Object> receiver,
StrictModeFlag strict_mode) { StrictModeFlag strict_mode,
int scope_position) {
Handle<Context> context = Handle<Context>(isolate->context()); Handle<Context> context = Handle<Context>(isolate->context());
Handle<Context> global_context = Handle<Context>(context->global_context()); Handle<Context> global_context = Handle<Context>(context->global_context());
@ -9511,7 +9510,8 @@ static ObjectPair CompileGlobalEval(Isolate* isolate,
source, source,
Handle<Context>(isolate->context()), Handle<Context>(isolate->context()),
context->IsGlobalContext(), context->IsGlobalContext(),
strict_mode); strict_mode,
scope_position);
if (shared.is_null()) return MakePair(Failure::Exception(), NULL); if (shared.is_null()) return MakePair(Failure::Exception(), NULL);
Handle<JSFunction> compiled = Handle<JSFunction> compiled =
isolate->factory()->NewFunctionFromSharedFunctionInfo( isolate->factory()->NewFunctionFromSharedFunctionInfo(
@ -9521,7 +9521,7 @@ static ObjectPair CompileGlobalEval(Isolate* isolate,
RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEval) { RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEval) {
ASSERT(args.length() == 4); ASSERT(args.length() == 5);
HandleScope scope(isolate); HandleScope scope(isolate);
Handle<Object> callee = args.at<Object>(0); Handle<Object> callee = args.at<Object>(0);
@ -9537,10 +9537,12 @@ RUNTIME_FUNCTION(ObjectPair, Runtime_ResolvePossiblyDirectEval) {
} }
CONVERT_STRICT_MODE_ARG(strict_mode, 3); CONVERT_STRICT_MODE_ARG(strict_mode, 3);
ASSERT(args[4]->IsSmi());
return CompileGlobalEval(isolate, return CompileGlobalEval(isolate,
args.at<String>(1), args.at<String>(1),
args.at<Object>(2), args.at<Object>(2),
strict_mode); strict_mode,
args.smi_at(4));
} }
@ -12154,7 +12156,8 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluate) {
Compiler::CompileEval(function_source, Compiler::CompileEval(function_source,
context, context,
context->IsGlobalContext(), context->IsGlobalContext(),
kNonStrictMode); kNonStrictMode,
RelocInfo::kNoPosition);
if (shared.is_null()) return Failure::Exception(); if (shared.is_null()) return Failure::Exception();
Handle<JSFunction> compiled_function = Handle<JSFunction> compiled_function =
isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context); isolate->factory()->NewFunctionFromSharedFunctionInfo(shared, context);
@ -12247,7 +12250,11 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_DebugEvaluateGlobal) {
// Currently, the eval code will be executed in non-strict mode, // Currently, the eval code will be executed in non-strict mode,
// even in the strict code context. // even in the strict code context.
Handle<SharedFunctionInfo> shared = Handle<SharedFunctionInfo> shared =
Compiler::CompileEval(source, context, is_global, kNonStrictMode); Compiler::CompileEval(source,
context,
is_global,
kNonStrictMode,
RelocInfo::kNoPosition);
if (shared.is_null()) return Failure::Exception(); if (shared.is_null()) return Failure::Exception();
Handle<JSFunction> compiled_function = Handle<JSFunction> compiled_function =
Handle<JSFunction>( Handle<JSFunction>(

View File

@ -259,7 +259,7 @@ namespace internal {
\ \
/* Eval */ \ /* Eval */ \
F(GlobalReceiver, 1, 1) \ F(GlobalReceiver, 1, 1) \
F(ResolvePossiblyDirectEval, 4, 2) \ F(ResolvePossiblyDirectEval, 5, 2) \
\ \
F(SetProperty, -1 /* 4 or 5 */, 1) \ F(SetProperty, -1 /* 4 or 5 */, 1) \
F(DefineOrRedefineDataProperty, 4, 1) \ F(DefineOrRedefineDataProperty, 4, 1) \

View File

@ -2096,7 +2096,10 @@ void FullCodeGenerator::EmitResolvePossiblyDirectEval(int arg_count) {
FLAG_harmony_scoping ? kStrictMode : strict_mode_flag(); FLAG_harmony_scoping ? kStrictMode : strict_mode_flag();
__ Push(Smi::FromInt(strict_mode)); __ Push(Smi::FromInt(strict_mode));
__ CallRuntime(Runtime::kResolvePossiblyDirectEval, 4); // Push the start position of the scope the calls resides in.
__ Push(Smi::FromInt(scope()->start_position()));
__ CallRuntime(Runtime::kResolvePossiblyDirectEval, 5);
} }