Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(90)

Unified Diff: src/runtime.cc

Issue 523051: Make the ResolvePossiblyDirectEval faster by avoiding the... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 10 years, 12 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/runtime.h ('k') | src/scopes.cc » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/runtime.cc
===================================================================
--- src/runtime.cc (revision 3528)
+++ src/runtime.cc (working copy)
@@ -5233,51 +5233,31 @@
}
-static Handle<JSFunction> GetBuiltinFunction(String* name) {
- LookupResult result;
- Top::global_context()->builtins()->LocalLookup(name, &result);
- return Handle<JSFunction>(JSFunction::cast(result.GetValue()));
-}
+static ObjectPair Runtime_ResolvePossiblyDirectEval(Arguments args) {
+ ASSERT(args.length() == 3);
+ if (!args[0]->IsJSFunction()) {
+ return MakePair(Top::ThrowIllegalOperation(), NULL);
+ }
-
-static Object* CompileDirectEval(Handle<String> source) {
- // Compute the eval context.
HandleScope scope;
+ Handle<JSFunction> callee = args.at<JSFunction>(0);
+ Handle<Object> receiver; // Will be overwritten.
+
+ // Compute the calling context.
+ Handle<Context> context = Handle<Context>(Top::context());
+#ifdef DEBUG
+ // Make sure Top::context() agrees with the old code that traversed
+ // the stack frames to compute the context.
StackFrameLocator locator;
JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
- Handle<Context> context(Context::cast(frame->context()));
- bool is_global = context->IsGlobalContext();
+ ASSERT(Context::cast(frame->context()) == *context);
+#endif
- // Compile source string in the current context.
- Handle<JSFunction> boilerplate = Compiler::CompileEval(
- source,
- context,
- is_global,
- Compiler::DONT_VALIDATE_JSON);
- if (boilerplate.is_null()) return Failure::Exception();
- Handle<JSFunction> fun =
- Factory::NewFunctionFromBoilerplate(boilerplate, context, NOT_TENURED);
- return *fun;
-}
-
-
-static Object* Runtime_ResolvePossiblyDirectEval(Arguments args) {
- ASSERT(args.length() == 2);
-
- HandleScope scope;
-
- CONVERT_ARG_CHECKED(JSFunction, callee, 0);
-
- Handle<Object> receiver;
-
// Find where the 'eval' symbol is bound. It is unaliased only if
// it is bound in the global context.
- StackFrameLocator locator;
- JavaScriptFrame* frame = locator.FindJavaScriptFrame(0);
- Handle<Context> context(Context::cast(frame->context()));
- int index;
- PropertyAttributes attributes;
- while (!context.is_null()) {
+ int index = -1;
+ PropertyAttributes attributes = ABSENT;
+ while (true) {
receiver = context->Lookup(Factory::eval_symbol(), FOLLOW_PROTOTYPE_CHAIN,
&index, &attributes);
// Stop search when eval is found or when the global context is
@@ -5296,46 +5276,42 @@
Handle<Object> name = Factory::eval_symbol();
Handle<Object> reference_error =
Factory::NewReferenceError("not_defined", HandleVector(&name, 1));
- return Top::Throw(*reference_error);
+ return MakePair(Top::Throw(*reference_error), NULL);
}
- if (context->IsGlobalContext()) {
- // 'eval' is bound in the global context, but it may have been overwritten.
- // Compare it to the builtin 'GlobalEval' function to make sure.
- Handle<JSFunction> global_eval =
- GetBuiltinFunction(Heap::global_eval_symbol());
- if (global_eval.is_identical_to(callee)) {
- // A direct eval call.
- if (args[1]->IsString()) {
- CONVERT_ARG_CHECKED(String, source, 1);
- // A normal eval call on a string. Compile it and return the
- // compiled function bound in the local context.
- Object* compiled_source = CompileDirectEval(source);
- if (compiled_source->IsFailure()) return compiled_source;
- receiver = Handle<Object>(frame->receiver());
- callee = Handle<JSFunction>(JSFunction::cast(compiled_source));
- } else {
- // An eval call that is not called on a string. Global eval
- // deals better with this.
- receiver = Handle<Object>(Top::global_context()->global());
- }
- } else {
- // 'eval' is overwritten. Just call the function with the given arguments.
- receiver = Handle<Object>(Top::global_context()->global());
- }
- } else {
+ if (!context->IsGlobalContext()) {
// 'eval' is not bound in the global context. Just call the function
// with the given arguments. This is not necessarily the global eval.
if (receiver->IsContext()) {
context = Handle<Context>::cast(receiver);
receiver = Handle<Object>(context->get(index));
+ } else if (receiver->IsJSContextExtensionObject()) {
+ receiver = Handle<JSObject>(Top::context()->global()->global_receiver());
}
+ return MakePair(*callee, *receiver);
}
- Handle<FixedArray> call = Factory::NewFixedArray(2);
- call->set(0, *callee);
- call->set(1, *receiver);
- return *call;
+ // 'eval' is bound in the global context, but it may have been overwritten.
+ // Compare it to the builtin 'GlobalEval' function to make sure.
+ if (*callee != Top::global_context()->global_eval_fun() ||
+ !args[1]->IsString()) {
+ return MakePair(*callee, Top::context()->global()->global_receiver());
+ }
+
+ // Deal with a normal eval call with a string argument. Compile it
+ // and return the compiled function bound in the local context.
+ Handle<String> source = args.at<String>(1);
+ Handle<JSFunction> boilerplate = Compiler::CompileEval(
+ source,
+ Handle<Context>(Top::context()),
+ Top::context()->IsGlobalContext(),
+ Compiler::DONT_VALIDATE_JSON);
+ if (boilerplate.is_null()) return MakePair(Failure::Exception(), NULL);
+ callee = Factory::NewFunctionFromBoilerplate(
+ boilerplate,
+ Handle<Context>(Top::context()),
+ NOT_TENURED);
+ return MakePair(*callee, args[2]);
}
« no previous file with comments | « src/runtime.h ('k') | src/scopes.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698