[turbofan] Avoid embedding type feedback vector into code.
authormstarzinger <mstarzinger@chromium.org>
Tue, 23 Jun 2015 08:27:16 +0000 (01:27 -0700)
committerCommit bot <commit-bot@chromium.org>
Tue, 23 Jun 2015 08:27:33 +0000 (08:27 +0000)
R=bmeurer@chromium.org

Review URL: https://codereview.chromium.org/1198263004

Cr-Commit-Position: refs/heads/master@{#29216}

src/compiler/ast-graph-builder.cc
src/compiler/ast-graph-builder.h
test/cctest/compiler/test-run-jscalls.cc

index 605f22f..0318165 100644 (file)
@@ -483,16 +483,6 @@ Node* AstGraphBuilder::GetFunctionClosure() {
 }
 
 
-Node* AstGraphBuilder::GetFeedbackVector() {
-  if (!feedback_vector_.is_set()) {
-    Node* vector =
-        jsgraph()->Constant(handle(info()->shared_info()->feedback_vector()));
-    feedback_vector_.set(vector);
-  }
-  return feedback_vector_.get();
-}
-
-
 void AstGraphBuilder::CreateFunctionContext(bool constant_context) {
   function_context_.set(constant_context
                             ? jsgraph()->HeapConstant(info()->context())
@@ -3297,7 +3287,7 @@ Node* AstGraphBuilder::BuildVariableLoad(Variable* variable,
         uint32_t check_bitset = ComputeBitsetForDynamicGlobal(variable);
         const Operator* op = javascript()->LoadDynamicGlobal(
             name, check_bitset, feedback, contextual_mode);
-        value = NewNode(op, GetFeedbackVector(), current_context());
+        value = NewNode(op, BuildLoadFeedbackVector(), current_context());
         states.AddToNode(value, bailout_id, combine);
       } else if (mode == DYNAMIC_LOCAL) {
         Variable* local = variable->local_if_not_shadowed();
@@ -3321,7 +3311,7 @@ Node* AstGraphBuilder::BuildVariableLoad(Variable* variable,
         uint32_t check_bitset = DynamicGlobalAccess::kFullCheckRequired;
         const Operator* op = javascript()->LoadDynamicGlobal(
             name, check_bitset, feedback, contextual_mode);
-        value = NewNode(op, GetFeedbackVector(), current_context());
+        value = NewNode(op, BuildLoadFeedbackVector(), current_context());
         states.AddToNode(value, bailout_id, combine);
       }
       return value;
@@ -3495,8 +3485,8 @@ static inline Node* Record(JSTypeFeedbackTable* js_type_feedback, Node* node,
 Node* AstGraphBuilder::BuildKeyedLoad(Node* object, Node* key,
                                       const VectorSlotPair& feedback) {
   const Operator* op = javascript()->LoadProperty(feedback);
-  return Record(js_type_feedback_,
-                NewNode(op, object, key, GetFeedbackVector()), feedback.slot());
+  Node* node = NewNode(op, object, key, BuildLoadFeedbackVector());
+  return Record(js_type_feedback_, node, feedback.slot());
 }
 
 
@@ -3505,8 +3495,8 @@ Node* AstGraphBuilder::BuildNamedLoad(Node* object, Handle<Name> name,
                                       ContextualMode mode) {
   const Operator* op =
       javascript()->LoadNamed(MakeUnique(name), feedback, mode);
-  return Record(js_type_feedback_, NewNode(op, object, GetFeedbackVector()),
-                feedback.slot());
+  Node* node = NewNode(op, object, BuildLoadFeedbackVector());
+  return Record(js_type_feedback_, node, feedback.slot());
 }
 
 
@@ -3514,7 +3504,8 @@ Node* AstGraphBuilder::BuildKeyedStore(Node* object, Node* key, Node* value,
                                        const VectorSlotPair& feedback,
                                        TypeFeedbackId id) {
   const Operator* op = javascript()->StoreProperty(language_mode(), feedback);
-  return Record(js_type_feedback_, NewNode(op, object, key, value), id);
+  Node* node = NewNode(op, object, key, value);
+  return Record(js_type_feedback_, node, id);
 }
 
 
@@ -3524,7 +3515,8 @@ Node* AstGraphBuilder::BuildNamedStore(Node* object, Handle<Name> name,
                                        TypeFeedbackId id) {
   const Operator* op =
       javascript()->StoreNamed(language_mode(), MakeUnique(name), feedback);
-  return Record(js_type_feedback_, NewNode(op, object, value), id);
+  Node* node = NewNode(op, object, value);
+  return Record(js_type_feedback_, node, id);
 }
 
 
@@ -3533,8 +3525,8 @@ Node* AstGraphBuilder::BuildNamedSuperLoad(Node* receiver, Node* home_object,
                                            const VectorSlotPair& feedback) {
   Node* name_node = jsgraph()->Constant(name);
   const Operator* op = javascript()->CallRuntime(Runtime::kLoadFromSuper, 3);
-  Node* value = NewNode(op, receiver, home_object, name_node);
-  return Record(js_type_feedback_, value, feedback.slot());
+  Node* node = NewNode(op, receiver, home_object, name_node);
+  return Record(js_type_feedback_, node, feedback.slot());
 }
 
 
@@ -3543,8 +3535,8 @@ Node* AstGraphBuilder::BuildKeyedSuperLoad(Node* receiver, Node* home_object,
                                            const VectorSlotPair& feedback) {
   const Operator* op =
       javascript()->CallRuntime(Runtime::kLoadKeyedFromSuper, 3);
-  Node* value = NewNode(op, receiver, home_object, key);
-  return Record(js_type_feedback_, value, feedback.slot());
+  Node* node = NewNode(op, receiver, home_object, key);
+  return Record(js_type_feedback_, node, feedback.slot());
 }
 
 
@@ -3555,8 +3547,8 @@ Node* AstGraphBuilder::BuildKeyedSuperStore(Node* receiver, Node* home_object,
                                         ? Runtime::kStoreKeyedToSuper_Strict
                                         : Runtime::kStoreKeyedToSuper_Sloppy;
   const Operator* op = javascript()->CallRuntime(function_id, 4);
-  Node* result = NewNode(op, receiver, home_object, key, value);
-  return Record(js_type_feedback_, result, id);
+  Node* node = NewNode(op, receiver, home_object, key, value);
+  return Record(js_type_feedback_, node, id);
 }
 
 
@@ -3568,8 +3560,8 @@ Node* AstGraphBuilder::BuildNamedSuperStore(Node* receiver, Node* home_object,
                                         ? Runtime::kStoreToSuper_Strict
                                         : Runtime::kStoreToSuper_Sloppy;
   const Operator* op = javascript()->CallRuntime(function_id, 4);
-  Node* result = NewNode(op, receiver, home_object, name_node, value);
-  return Record(js_type_feedback_, result, id);
+  Node* node = NewNode(op, receiver, home_object, name_node, value);
+  return Record(js_type_feedback_, node, id);
 }
 
 
@@ -3579,6 +3571,13 @@ Node* AstGraphBuilder::BuildLoadObjectField(Node* object, int offset) {
 }
 
 
+Node* AstGraphBuilder::BuildLoadImmutableObjectField(Node* object, int offset) {
+  return graph()->NewNode(jsgraph()->machine()->Load(kMachAnyTagged), object,
+                          jsgraph()->IntPtrConstant(offset - kHeapObjectTag),
+                          graph()->start(), graph()->start());
+}
+
+
 Node* AstGraphBuilder::BuildLoadBuiltinsObject() {
   Node* global = BuildLoadGlobalObject();
   Node* builtins =
@@ -3602,6 +3601,19 @@ Node* AstGraphBuilder::BuildLoadGlobalProxy() {
 }
 
 
+Node* AstGraphBuilder::BuildLoadFeedbackVector() {
+  if (!feedback_vector_.is_set()) {
+    Node* closure = GetFunctionClosure();
+    Node* shared = BuildLoadImmutableObjectField(
+        closure, JSFunction::kSharedFunctionInfoOffset);
+    Node* vector = BuildLoadImmutableObjectField(
+        shared, SharedFunctionInfo::kFeedbackVectorOffset);
+    feedback_vector_.set(vector);
+  }
+  return feedback_vector_.get();
+}
+
+
 Node* AstGraphBuilder::BuildLoadExternal(ExternalReference reference,
                                          MachineType type) {
   return NewNode(jsgraph()->machine()->Load(type),
index 7b8ebfa..e3cf7b5 100644 (file)
@@ -88,7 +88,6 @@ class AstGraphBuilder : public AstVisitor {
   // Nodes representing values in the activation record.
   SetOncePointer<Node> function_closure_;
   SetOncePointer<Node> function_context_;
-  SetOncePointer<Node> feedback_vector_;
 
   // Tracks how many try-blocks are currently entered.
   int try_catch_nesting_level_;
@@ -98,6 +97,9 @@ class AstGraphBuilder : public AstVisitor {
   int input_buffer_size_;
   Node** input_buffer_;
 
+  // Optimization to cache loaded feedback vector.
+  SetOncePointer<Node> feedback_vector_;
+
   // Control nodes that exit the function body.
   ZoneVector<Node*> exit_controls_;
 
@@ -155,9 +157,6 @@ class AstGraphBuilder : public AstVisitor {
   Node* GetFunctionClosureForContext();
   Node* GetFunctionClosure();
 
-  // Get or create the node that represents the functions type feedback vector.
-  Node* GetFeedbackVector();
-
   // Node creation helpers.
   Node* NewNode(const Operator* op, bool incomplete = false) {
     return MakeNode(op, 0, static_cast<Node**>(NULL), incomplete);
@@ -312,8 +311,11 @@ class AstGraphBuilder : public AstVisitor {
   Node* BuildLoadBuiltinsObject();
   Node* BuildLoadGlobalObject();
   Node* BuildLoadGlobalProxy();
-  Node* BuildLoadClosure();
+  Node* BuildLoadFeedbackVector();
+
+  // Builder for accessing a (potentially immutable) object field.
   Node* BuildLoadObjectField(Node* object, int offset);
+  Node* BuildLoadImmutableObjectField(Node* object, int offset);
 
   // Builders for accessing external references.
   Node* BuildLoadExternal(ExternalReference ref, MachineType type);
index a622af8..8de2d7a 100644 (file)
@@ -242,6 +242,7 @@ TEST(ContextLoadedFromActivation) {
   i::Handle<i::Object> ofun = v8::Utils::OpenHandle(*value);
   i::Handle<i::JSFunction> jsfun = Handle<JSFunction>::cast(ofun);
   jsfun->set_code(T.function->code());
+  jsfun->set_shared(T.function->shared());
   context->Global()->Set(v8_str("foo"), v8::Utils::ToLocal(jsfun));
   CompileRun("var x = 24;");
   ExpectInt32("foo();", 24);
@@ -263,6 +264,7 @@ TEST(BuiltinLoadedFromActivation) {
   i::Handle<i::Object> ofun = v8::Utils::OpenHandle(*value);
   i::Handle<i::JSFunction> jsfun = Handle<JSFunction>::cast(ofun);
   jsfun->set_code(T.function->code());
+  jsfun->set_shared(T.function->shared());
   context->Global()->Set(v8_str("foo"), v8::Utils::ToLocal(jsfun));
   CompileRun("var x = 24;");
   ExpectObject("foo()", context->Global());