Revision: 23205
Author:   [email protected]
Date:     Tue Aug 19 15:16:23 2014 UTC
Log:      Load global object and builtins from activation.

BUG=
[email protected]

Review URL: https://codereview.chromium.org/474633003
http://code.google.com/p/v8/source/detail?r=23205

Modified:
 /branches/bleeding_edge/src/compiler/ast-graph-builder.cc
 /branches/bleeding_edge/src/compiler/ast-graph-builder.h
 /branches/bleeding_edge/test/cctest/compiler/test-run-jscalls.cc

=======================================
--- /branches/bleeding_edge/src/compiler/ast-graph-builder.cc Mon Aug 18 12:35:34 2014 UTC +++ /branches/bleeding_edge/src/compiler/ast-graph-builder.cc Tue Aug 19 15:16:23 2014 UTC
@@ -6,6 +6,7 @@

 #include "src/compiler.h"
 #include "src/compiler/control-builders.h"
+#include "src/compiler/machine-operator.h"
 #include "src/compiler/node-properties.h"
 #include "src/compiler/node-properties-inl.h"
 #include "src/full-codegen.h"
@@ -737,13 +738,12 @@
           test_should_filter.If(should_filter_cond);
           test_should_filter.Then();
           value = environment()->Pop();
-          // TODO(dcarney): Better load from function context.
-          // See comment in BuildLoadBuiltinsObject.
-          Handle<JSFunction> function(JSFunction::cast(
-              info()->context()->builtins()->javascript_builtin(
-                  Builtins::FILTER_KEY)));
+          Node* builtins = BuildLoadBuiltinsObject();
+          Node* function = BuildLoadObjectField(
+              builtins,
+ JSBuiltinsObject::OffsetOfFunctionWithId(Builtins::FILTER_KEY));
           // Callee.
-          environment()->Push(jsgraph()->HeapConstant(function));
+          environment()->Push(function);
           // Receiver.
           environment()->Push(obj);
           // Args.
@@ -875,10 +875,11 @@


 void AstGraphBuilder::VisitRegExpLiteral(RegExpLiteral* expr) {
-  Handle<JSFunction> closure = info()->closure();
+  Node* closure = GetFunctionClosure();

   // Create node to materialize a regular expression literal.
-  Node* literals_array = jsgraph()->Constant(handle(closure->literals()));
+  Node* literals_array =
+      BuildLoadObjectField(closure, JSFunction::kLiteralsOffset);
   Node* literal_index = jsgraph()->Constant(expr->literal_index());
   Node* pattern = jsgraph()->Constant(expr->pattern());
   Node* flags = jsgraph()->Constant(expr->flags());
@@ -889,11 +890,12 @@


 void AstGraphBuilder::VisitObjectLiteral(ObjectLiteral* expr) {
-  Handle<JSFunction> closure = info()->closure();
+  Node* closure = GetFunctionClosure();

   // Create node to deep-copy the literal boilerplate.
   expr->BuildConstantProperties(isolate());
-  Node* literals_array = jsgraph()->Constant(handle(closure->literals()));
+  Node* literals_array =
+      BuildLoadObjectField(closure, JSFunction::kLiteralsOffset);
   Node* literal_index = jsgraph()->Constant(expr->literal_index());
   Node* constants = jsgraph()->Constant(expr->constant_properties());
   Node* flags = jsgraph()->Constant(expr->ComputeFlags());
@@ -998,11 +1000,12 @@


 void AstGraphBuilder::VisitArrayLiteral(ArrayLiteral* expr) {
-  Handle<JSFunction> closure = info()->closure();
+  Node* closure = GetFunctionClosure();

   // Create node to deep-copy the literal boilerplate.
   expr->BuildConstantElements(isolate());
-  Node* literals_array = jsgraph()->Constant(handle(closure->literals()));
+  Node* literals_array =
+      BuildLoadObjectField(closure, JSFunction::kLiteralsOffset);
   Node* literal_index = jsgraph()->Constant(expr->literal_index());
   Node* constants = jsgraph()->Constant(expr->constant_elements());
   Node* flags = jsgraph()->Constant(expr->ComputeFlags());
@@ -1936,27 +1939,30 @@
   UNREACHABLE();
   return NULL;
 }
+
+
+Node* AstGraphBuilder::BuildLoadObjectField(Node* object, int offset) {
+  // TODO(sigurds) Use simplified load here once it is ready.
+  MachineOperatorBuilder machine(zone());
+  Node* field_load = NewNode(machine.Load(kMachAnyTagged), object,
+ jsgraph_->Int32Constant(offset - kHeapObjectTag));
+  return field_load;
+}


 Node* AstGraphBuilder::BuildLoadBuiltinsObject() {
- // TODO(mstarzinger): Better load from function context, otherwise optimized
-  // code cannot be shared across native contexts.
-  return jsgraph()->Constant(handle(info()->context()->builtins()));
+  Node* global = BuildLoadGlobalObject();
+  Node* builtins =
+      BuildLoadObjectField(global, JSGlobalObject::kBuiltinsOffset);
+  return builtins;
 }


 Node* AstGraphBuilder::BuildLoadGlobalObject() {
-#if 0
   Node* context = GetFunctionContext();
-  // TODO(mstarzinger): Use mid-level operator on FixedArray instead of the
-  // JS-level operator that targets JSObject.
-  Node* index = jsgraph()->Constant(Context::GLOBAL_OBJECT_INDEX);
-  return NewNode(javascript()->LoadProperty(), context, index);
-#else
- // TODO(mstarzinger): Better load from function context, otherwise optimized
-  // code cannot be shared across native contexts. See unused code above.
-  return jsgraph()->Constant(handle(info()->context()->global_object()));
-#endif
+  Operator* load_op =
+      javascript()->LoadContext(0, Context::GLOBAL_OBJECT_INDEX, true);
+  return NewNode(load_op, context);
 }


=======================================
--- /branches/bleeding_edge/src/compiler/ast-graph-builder.h Wed Aug 13 10:22:53 2014 UTC +++ /branches/bleeding_edge/src/compiler/ast-graph-builder.h Tue Aug 19 15:16:23 2014 UTC
@@ -88,6 +88,7 @@
   Node* BuildLoadBuiltinsObject();
   Node* BuildLoadGlobalObject();
   Node* BuildLoadClosure();
+  Node* BuildLoadObjectField(Node* object, int offset);

   // Builders for automatic type conversion.
   Node* BuildToBoolean(Node* value);
=======================================
--- /branches/bleeding_edge/test/cctest/compiler/test-run-jscalls.cc Tue Aug 19 11:24:24 2014 UTC +++ /branches/bleeding_edge/test/cctest/compiler/test-run-jscalls.cc Tue Aug 19 15:16:23 2014 UTC
@@ -245,3 +245,88 @@

   T.CheckCall(T.Val(42), T.Val("x"), T.undefined());
 }
+
+#if V8_TURBOFAN_TARGET
+
+TEST(ContextLoadedFromActivation) {
+  i::FLAG_turbo_filter = "*";
+  i::FLAG_always_opt = true;
+  i::FLAG_context_specialization = false;
+
+  const char* script =
+      "var x = 42;"
+      "(function() {"
+      "  return function () { return x };"
+      "})()";
+
+  v8::Isolate* isolate = CcTest::isolate();
+  v8::HandleScope outer(isolate);
+  v8::Local<v8::Value> fun;
+  {
+    v8::Local<v8::Context> env = v8::Context::New(isolate);
+    env->Enter();
+    CompileRun("var x = 42;");
+    fun = CompileRun(script);
+    env->Global()->Set(v8_str("foo"), fun);
+    ExpectInt32("foo();", 42);
+    env->Exit();
+  }
+
+  {
+    v8::Local<v8::Context> env = v8::Context::New(isolate);
+    env->Enter();
+    v8::Local<v8::Value> fun2 = CompileRun(script);
+    i::Handle<i::Object> oifun = v8::Utils::OpenHandle(*fun);
+    i::Handle<i::JSFunction> ifun = Handle<JSFunction>::cast(oifun);
+    i::Handle<i::Object> oifun2 = v8::Utils::OpenHandle(*fun2);
+    i::Handle<i::JSFunction> ifun2 = Handle<JSFunction>::cast(oifun2);
+    ifun2->set_code(ifun->code());
+    env->Global()->Set(v8_str("foo"), fun2);
+    CompileRun("var x = 24;");
+    ExpectInt32("foo();", 24);
+    env->Exit();
+  }
+}
+
+
+TEST(BuiltinLoadedFromActivation) {
+  i::FLAG_turbo_filter = "*";
+  i::FLAG_always_opt = true;
+  i::FLAG_context_specialization = false;
+
+  const char* script =
+      "var x = 42;"
+      "(function() {"
+      "  return function () { return this; };"
+      "})()";
+
+  v8::Isolate* isolate = CcTest::isolate();
+  v8::HandleScope outer(isolate);
+  v8::Local<v8::Value> fun;
+  {
+    v8::Local<v8::Context> env = v8::Context::New(isolate);
+    env->Enter();
+    CompileRun("var x = 42;");
+    fun = CompileRun(script);
+    env->Global()->Set(v8_str("foo"), fun);
+    ExpectObject("foo()", env->Global());
+    env->Exit();
+  }
+
+  {
+    v8::Local<v8::Context> env = v8::Context::New(isolate);
+    env->Enter();
+    v8::Local<v8::Value> fun2 = CompileRun(script);
+    i::Handle<i::Object> oifun = v8::Utils::OpenHandle(*fun);
+    i::Handle<i::JSFunction> ifun = Handle<JSFunction>::cast(oifun);
+    i::Handle<i::Object> oifun2 = v8::Utils::OpenHandle(*fun2);
+    i::Handle<i::JSFunction> ifun2 = Handle<JSFunction>::cast(oifun2);
+    ifun2->set_code(ifun->code());
+    env->Global()->Set(v8_str("foo"), fun2);
+    CompileRun("var x = 24;");
+    ExpectObject("foo()", env->Global());
+    env->Exit();
+  }
+}
+
+#endif  // V8_TURBO_TARGET

--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
--- You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to