Revision: 23275
Author:   [email protected]
Date:     Thu Aug 21 12:40:10 2014 UTC
Log:      Reland "Load global object and builtins from activation."

Reland fixes:
Don't set string flags (doing so leaks memory).

Load closure from activation for building literals.

[email protected]

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

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

=======================================
--- /branches/bleeding_edge/src/compiler/ast-graph-builder.cc Thu Aug 21 11:56:46 2014 UTC +++ /branches/bleeding_edge/src/compiler/ast-graph-builder.cc Thu Aug 21 12:40:10 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"
@@ -701,13 +702,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.
@@ -840,10 +840,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());
@@ -854,11 +855,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());
@@ -963,11 +965,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());
@@ -1906,27 +1909,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 Thu Aug 21 11:56:46 2014 UTC +++ /branches/bleeding_edge/src/compiler/ast-graph-builder.h Thu Aug 21 12:40:10 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/src/compiler/pipeline.cc Wed Aug 20 13:05:03 2014 UTC +++ /branches/bleeding_edge/src/compiler/pipeline.cc Thu Aug 21 12:40:10 2014 UTC
@@ -186,7 +186,7 @@

   VerifyAndPrintGraph(&graph, "Initial untyped");

-  if (FLAG_context_specialization) {
+  if (context_specialization_) {
     SourcePositionTable::Scope pos(&source_positions,
                                    SourcePosition::Unknown());
     // Specialize the code to the context as aggressively as possible.
=======================================
--- /branches/bleeding_edge/src/compiler/pipeline.h Wed Aug 13 14:05:37 2014 UTC +++ /branches/bleeding_edge/src/compiler/pipeline.h Thu Aug 21 12:40:10 2014 UTC
@@ -24,7 +24,8 @@

 class Pipeline {
  public:
-  explicit Pipeline(CompilationInfo* info) : info_(info) {}
+  explicit Pipeline(CompilationInfo* info)
+ : info_(info), context_specialization_(FLAG_context_specialization) {}

   // Run the entire pipeline and generate a handle to a code object.
   Handle<Code> GenerateCode();
@@ -39,9 +40,14 @@

   static void SetUp();
   static void TearDown();
+  bool context_specialization() { return context_specialization_; }
+  void set_context_specialization(bool context_specialization) {
+    context_specialization_ = context_specialization;
+  }

  private:
   CompilationInfo* info_;
+  bool context_specialization_;

   CompilationInfo* info() const { return info_; }
   Isolate* isolate() { return info_->isolate(); }
=======================================
--- /branches/bleeding_edge/test/cctest/compiler/function-tester.h Tue Aug 19 11:24:24 2014 UTC +++ /branches/bleeding_edge/test/cctest/compiler/function-tester.h Thu Aug 21 12:40:10 2014 UTC
@@ -26,10 +26,13 @@

 class FunctionTester : public InitializedHandleScope {
  public:
-  explicit FunctionTester(const char* source)
+  explicit FunctionTester(const char* source, bool context_specialization =
+ FLAG_context_specialization)
       : isolate(main_isolate()),
-        function((FLAG_allow_natives_syntax = true, NewFunction(source))) {
+        function((FLAG_allow_natives_syntax = true, NewFunction(source))),
+        context_specialization_(context_specialization) {
     Compile(function);
+    USE(context_specialization_);
   }

   Isolate* isolate;
@@ -52,6 +55,7 @@
     EnsureDeoptimizationSupport(&info);

     Pipeline pipeline(&info);
+    pipeline.set_context_specialization(context_specialization_);
     Handle<Code> code = pipeline.GenerateCode();

     CHECK(!code.is_null());
@@ -188,6 +192,9 @@
   Handle<Object> true_value() { return isolate->factory()->true_value(); }

Handle<Object> false_value() { return isolate->factory()->false_value(); }
+
+ private:
+  bool context_specialization_;
 };
 }
 }
=======================================
--- /branches/bleeding_edge/test/cctest/compiler/test-run-jscalls.cc Tue Aug 19 16:07:15 2014 UTC +++ /branches/bleeding_edge/test/cctest/compiler/test-run-jscalls.cc Thu Aug 21 12:40:10 2014 UTC
@@ -245,3 +245,45 @@

   T.CheckCall(T.Val(42), T.Val("x"), T.undefined());
 }
+
+
+TEST(ContextLoadedFromActivation) {
+  const char* script =
+      "var x = 42;"
+      "(function() {"
+      "  return function () { return x };"
+      "})()";
+
+  // Disable context specialization.
+  FunctionTester T(script, false);
+  v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
+  v8::Context::Scope scope(context);
+  v8::Local<v8::Value> value = CompileRun(script);
+  i::Handle<i::Object> ofun = v8::Utils::OpenHandle(*value);
+  i::Handle<i::JSFunction> jsfun = Handle<JSFunction>::cast(ofun);
+  jsfun->set_code(T.function->code());
+  context->Global()->Set(v8_str("foo"), v8::Utils::ToLocal(jsfun));
+  CompileRun("var x = 24;");
+  ExpectInt32("foo();", 24);
+}
+
+
+TEST(BuiltinLoadedFromActivation) {
+  const char* script =
+      "var x = 42;"
+      "(function() {"
+      "  return function () { return this; };"
+      "})()";
+
+  // Disable context specialization.
+  FunctionTester T(script, false);
+  v8::Local<v8::Context> context = v8::Context::New(CcTest::isolate());
+  v8::Context::Scope scope(context);
+  v8::Local<v8::Value> value = CompileRun(script);
+  i::Handle<i::Object> ofun = v8::Utils::OpenHandle(*value);
+  i::Handle<i::JSFunction> jsfun = Handle<JSFunction>::cast(ofun);
+  jsfun->set_code(T.function->code());
+  context->Global()->Set(v8_str("foo"), v8::Utils::ToLocal(jsfun));
+  CompileRun("var x = 24;");
+  ExpectObject("foo()", context->Global());
+}

--
--
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