Revision: 16260
Author:   [email protected]
Date:     Wed Aug 21 14:49:56 2013 UTC
Log: Pass checked values to HLoadNamedField, removing the need for extra type-check field.

[email protected]

Review URL: https://chromiumcodereview.appspot.com/22831003
http://code.google.com/p/v8/source/detail?r=16260

Modified:
 /branches/bleeding_edge/src/code-stubs-hydrogen.cc
 /branches/bleeding_edge/src/hydrogen-escape-analysis.cc
 /branches/bleeding_edge/src/hydrogen-instructions.cc
 /branches/bleeding_edge/src/hydrogen-instructions.h
 /branches/bleeding_edge/src/hydrogen.cc
 /branches/bleeding_edge/src/hydrogen.h

=======================================
--- /branches/bleeding_edge/src/code-stubs-hydrogen.cc Fri Aug 9 18:40:10 2013 UTC +++ /branches/bleeding_edge/src/code-stubs-hydrogen.cc Wed Aug 21 14:49:56 2013 UTC
@@ -352,7 +352,7 @@
   HObjectAccess access = HObjectAccess::ForAllocationSiteTransitionInfo();
HInstruction* boilerplate = Add<HLoadNamedField>(allocation_site, access);
   if (mode == FastCloneShallowArrayStub::CLONE_ANY_ELEMENTS) {
-    HValue* elements = AddLoadElements(boilerplate, NULL);
+    HValue* elements = AddLoadElements(boilerplate);

     IfBuilder if_fixed_cow(this);
     if_fixed_cow.If<HCompareMap>(elements, factory->fixed_cow_array_map());
@@ -513,7 +513,7 @@
   HObjectAccess access = casted_stub()->is_inobject() ?
       HObjectAccess::ForJSObjectOffset(casted_stub()->offset(), rep) :
       HObjectAccess::ForBackingStoreOffset(casted_stub()->offset(), rep);
- return AddInstruction(BuildLoadNamedField(GetParameter(0), access, NULL));
+  return AddInstruction(BuildLoadNamedField(GetParameter(0), access));
 }


@@ -528,7 +528,7 @@
   HObjectAccess access = casted_stub()->is_inobject() ?
       HObjectAccess::ForJSObjectOffset(casted_stub()->offset(), rep) :
       HObjectAccess::ForBackingStoreOffset(casted_stub()->offset(), rep);
- return AddInstruction(BuildLoadNamedField(GetParameter(0), access, NULL));
+  return AddInstruction(BuildLoadNamedField(GetParameter(0), access));
 }


=======================================
--- /branches/bleeding_edge/src/hydrogen-escape-analysis.cc Mon Aug 12 09:26:18 2013 UTC +++ /branches/bleeding_edge/src/hydrogen-escape-analysis.cc Wed Aug 21 14:49:56 2013 UTC
@@ -215,7 +215,6 @@
for (HUseIterator it(mapcheck->uses()); !it.Done(); it.Advance()) {
             if (!it.value()->IsLoadNamedField()) continue;
             HLoadNamedField* load = HLoadNamedField::cast(it.value());
-            ASSERT(load->typecheck() == mapcheck);
             load->ClearTypeCheck();
           }
           ASSERT(mapcheck->HasNoUses());
=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.cc Mon Aug 19 10:55:51 2013 UTC +++ /branches/bleeding_edge/src/hydrogen-instructions.cc Wed Aug 21 14:49:56 2013 UTC
@@ -2849,10 +2849,6 @@
 void HLoadNamedField::PrintDataTo(StringStream* stream) {
   object()->PrintNameTo(stream);
   access_.PrintTo(stream);
-  if (HasTypeCheck()) {
-    stream->Add(" ");
-    typecheck()->PrintNameTo(stream);
-  }
 }


=======================================
--- /branches/bleeding_edge/src/hydrogen-instructions.h Tue Aug 20 11:10:24 2013 UTC +++ /branches/bleeding_edge/src/hydrogen-instructions.h Wed Aug 21 14:49:56 2013 UTC
@@ -1370,6 +1370,9 @@
   }

   DECLARE_CONCRETE_INSTRUCTION(CompareMap)
+
+ protected:
+  virtual int RedefinedOperandIndex() { return 0; }

  private:
   Handle<Map> map_;
@@ -2574,6 +2577,8 @@
     }
     return true;
   }
+
+  virtual int RedefinedOperandIndex() { return 0; }

  private:
   void Add(Handle<Map> map, Zone* zone) {
@@ -2698,6 +2703,8 @@
     HCheckInstanceType* b = HCheckInstanceType::cast(other);
     return check_ == b->check_;
   }
+
+  virtual int RedefinedOperandIndex() { return 0; }

  private:
   enum Check {
@@ -5585,20 +5592,13 @@
 };


-class HLoadNamedField V8_FINAL : public HTemplateInstruction<2> {
+class HLoadNamedField V8_FINAL : public HTemplateInstruction<1> {
  public:
   DECLARE_INSTRUCTION_FACTORY_P2(HLoadNamedField, HValue*, HObjectAccess);
-  DECLARE_INSTRUCTION_FACTORY_P3(HLoadNamedField, HValue*, HObjectAccess,
-                                 HValue*);

   HValue* object() { return OperandAt(0); }
-  HValue* typecheck() {
-    ASSERT(HasTypeCheck());
-    return OperandAt(1);
-  }
-
-  bool HasTypeCheck() const { return OperandAt(0) != OperandAt(1); }
-  void ClearTypeCheck() { SetOperandAt(1, object()); }
+  bool HasTypeCheck() { return object()->IsCheckMaps(); }
+  void ClearTypeCheck() { SetOperandAt(0, object()->ActualValue()); }
   HObjectAccess access() const { return access_; }
   Representation field_representation() const {
       return access_.representation();
@@ -5624,13 +5624,9 @@
   }

  private:
-  HLoadNamedField(HValue* object,
-                  HObjectAccess access,
-                  HValue* typecheck = NULL)
-      : access_(access) {
+  HLoadNamedField(HValue* object, HObjectAccess access) : access_(access) {
     ASSERT(object != NULL);
     SetOperandAt(0, object);
-    SetOperandAt(1, typecheck != NULL ? typecheck : object);

     Representation representation = access.representation();
     if (representation.IsSmi()) {
=======================================
--- /branches/bleeding_edge/src/hydrogen.cc     Tue Aug 20 11:10:24 2013 UTC
+++ /branches/bleeding_edge/src/hydrogen.cc     Wed Aug 21 14:49:56 2013 UTC
@@ -1191,7 +1191,7 @@
   }

   if (!IsSimpleMapChangeTransition(from_kind, to_kind)) {
-    HInstruction* elements = AddLoadElements(object, NULL);
+    HInstruction* elements = AddLoadElements(object);

     HInstruction* empty_fixed_array = Add<HConstant>(
         isolate()->factory()->empty_fixed_array());
@@ -1222,7 +1222,7 @@
     HValue* object,
     HValue* key,
     HValue* val,
-    HCheckMaps* mapcheck,
+    HCheckMaps* checked_object,
     bool is_js_array,
     ElementsKind elements_kind,
     bool is_store,
@@ -1237,13 +1237,14 @@
   // generated store code.
   if ((elements_kind == FAST_HOLEY_ELEMENTS) ||
       (elements_kind == FAST_ELEMENTS && is_store)) {
-    if (mapcheck != NULL) {
-      mapcheck->ClearGVNFlag(kDependsOnElementsKind);
+    if (checked_object != NULL) {
+      checked_object->ClearGVNFlag(kDependsOnElementsKind);
     }
   }
+  if (checked_object != NULL) object = checked_object;
   bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind);
   bool fast_elements = IsFastObjectElementsKind(elements_kind);
-  HValue* elements = AddLoadElements(object, mapcheck);
+  HValue* elements = AddLoadElements(object);
   if (is_store && (fast_elements || fast_smi_only_elements) &&
       store_mode != STORE_NO_TRANSITION_HANDLE_COW) {
     HCheckMaps* check_cow_map = Add<HCheckMaps>(
@@ -1252,8 +1253,8 @@
   }
   HInstruction* length = NULL;
   if (is_js_array) {
-    length = Add<HLoadNamedField>(object,
-        HObjectAccess::ForArrayLength(elements_kind), mapcheck);
+    length = Add<HLoadNamedField>(
+        object, HObjectAccess::ForArrayLength(elements_kind));
   } else {
     length = AddLoadFixedArrayLength(elements);
   }
@@ -1283,7 +1284,7 @@
           Add<HLoadExternalArrayPointer>(elements);
       return AddExternalArrayElementAccess(
           external_elements, checked_key, val,
-          mapcheck, elements_kind, is_store);
+          checked_object, elements_kind, is_store);
     }
   }
   ASSERT(fast_smi_only_elements ||
@@ -1320,7 +1321,7 @@
       }
     }
   }
-  return AddFastElementAccess(elements, checked_key, val, mapcheck,
+  return AddFastElementAccess(elements, checked_key, val, checked_object,
elements_kind, is_store, load_mode, store_mode);
 }

@@ -1493,11 +1494,8 @@
 }


-HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object,
-                                                HValue* typecheck) {
-  return Add<HLoadNamedField>(object,
-                              HObjectAccess::ForElementsPointer(),
-                              typecheck);
+HLoadNamedField* HGraphBuilder::AddLoadElements(HValue* object) {
+  return Add<HLoadNamedField>(object, HObjectAccess::ForElementsPointer());
 }


@@ -1713,7 +1711,7 @@
   if (length > 0) {
     // Get hold of the elements array of the boilerplate and setup the
     // elements pointer in the resulting object.
-    HValue* boilerplate_elements = AddLoadElements(boilerplate, NULL);
+    HValue* boilerplate_elements = AddLoadElements(boilerplate);
HValue* object_elements = Add<HInnerAllocatedObject>(object, elems_offset);
     Add<HStoreNamedField>(object, HObjectAccess::ForElementsPointer(),
                           object_elements);
@@ -1846,7 +1844,7 @@
     // map, because we can just load the map in that case.
     HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
     return builder()->AddInstruction(
- builder()->BuildLoadNamedField(constructor_function_, access, NULL));
+        builder()->BuildLoadNamedField(constructor_function_, access));
   }

   HInstruction* native_context = builder()->BuildGetNativeContext();
@@ -1867,7 +1865,7 @@
   // Find the map near the constructor function
   HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap();
   return builder()->AddInstruction(
-      builder()->BuildLoadNamedField(constructor_function_, access, NULL));
+      builder()->BuildLoadNamedField(constructor_function_, access));
 }


@@ -4312,7 +4310,6 @@
   int data_size = 0;
   int pointer_size = 0;
   int max_properties = kMaxFastLiteralProperties;
-  HCheckMaps* type_check = NULL;
   if (IsFastLiteral(original_boilerplate_object,
                     kMaxFastLiteralDepth,
                     &max_properties,
@@ -4350,7 +4347,7 @@
     // De-opt if elements kind changed from boilerplate_elements_kind.
     Handle<Map> map = Handle<Map>(original_boilerplate_object->map(),
                                   isolate());
-    type_check = Add<HCheckMaps>(literal, map, top_info());
+    literal = Add<HCheckMaps>(literal, map, top_info());
   }

   // The array is expected in the bailout environment during computation
@@ -4371,7 +4368,7 @@
     HValue* value = Pop();
     if (!Smi::IsValid(i)) return Bailout(kNonSmiKeyInArrayLiteral);

-    elements = AddLoadElements(literal, type_check);
+    elements = AddLoadElements(literal);

     HValue* key = Add<HConstant>(i);

@@ -4594,8 +4591,8 @@
   if (count == types->length()) {
     // Everything matched; can use monomorphic load.
     BuildCheckHeapObject(object);
-    HCheckMaps* type_check = Add<HCheckMaps>(object, types);
-    return BuildLoadNamedField(object, access, type_check);
+    HCheckMaps* checked_object = Add<HCheckMaps>(object, types);
+    return BuildLoadNamedField(checked_object, access);
   }

   if (count != 0) return NULL;
@@ -4616,14 +4613,14 @@
   if (!lookup.IsField()) return NULL;

   BuildCheckHeapObject(object);
-  HCheckMaps* type_check = Add<HCheckMaps>(object, types);
+  Add<HCheckMaps>(object, types);

   Handle<JSObject> holder(lookup.holder());
   Handle<Map> holder_map(holder->map());
-  BuildCheckPrototypeMaps(Handle<JSObject>::cast(prototype), holder);
-  HValue* holder_value = Add<HConstant>(holder);
-  return BuildLoadNamedField(holder_value,
-      HObjectAccess::ForField(holder_map, &lookup, name), type_check);
+  HValue* checked_holder = BuildCheckPrototypeMaps(
+      Handle<JSObject>::cast(prototype), holder);
+  return BuildLoadNamedField(checked_holder,
+      HObjectAccess::ForField(holder_map, &lookup, name));
 }


@@ -4698,7 +4695,7 @@
       // TODO(verwaest): Merge logic with BuildLoadNamedMonomorphic.
       if (lookup.IsField()) {
         HObjectAccess access = HObjectAccess::ForField(map, &lookup, name);
- HLoadNamedField* load = BuildLoadNamedField(object, access, compare);
+        HLoadNamedField* load = BuildLoadNamedField(compare, access);
         load->set_position(expr->position());
         AddInstruction(load);
         if (!ast_context()->IsEffect()) Push(load);
@@ -5371,32 +5368,29 @@


 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object,
-                                                    HObjectAccess access,
-                                                    HValue* typecheck) {
+                                                    HObjectAccess access) {
   if (FLAG_track_double_fields && access.representation().IsDouble()) {
     // load the heap number
     HLoadNamedField* heap_number = Add<HLoadNamedField>(
         object, access.WithRepresentation(Representation::Tagged()));
     heap_number->set_type(HType::HeapNumber());
     // load the double value from it
-    return New<HLoadNamedField>(heap_number,
-                                HObjectAccess::ForHeapNumberValue(),
-                                typecheck);
+    return New<HLoadNamedField>(
+        heap_number, HObjectAccess::ForHeapNumberValue());
   }
-  return New<HLoadNamedField>(object, access, typecheck);
+  return New<HLoadNamedField>(object, access);
 }


 HInstruction* HGraphBuilder::BuildLoadStringLength(HValue* object,
-                                                   HValue* typecheck) {
+ HValue* checked_string) {
   if (FLAG_fold_constants && object->IsConstant()) {
     HConstant* constant = HConstant::cast(object);
     if (constant->HasStringValue()) {
       return New<HConstant>(constant->StringValue()->length());
     }
   }
-  return BuildLoadNamedField(
-      object, HObjectAccess::ForStringLength(), typecheck);
+ return BuildLoadNamedField(checked_string, HObjectAccess::ForStringLength());
 }


@@ -5435,18 +5429,18 @@
   // Handle access to various length properties
   if (name->Equals(isolate()->heap()->length_string())) {
     if (map->instance_type() == JS_ARRAY_TYPE) {
-      HCheckMaps* type_check = AddCheckMap(object, map);
-      return New<HLoadNamedField>(object,
-          HObjectAccess::ForArrayLength(map->elements_kind()), type_check);
+      HCheckMaps* checked_object = AddCheckMap(object, map);
+      return New<HLoadNamedField>(
+ checked_object, HObjectAccess::ForArrayLength(map->elements_kind()));
     }
   }

   LookupResult lookup(isolate());
   map->LookupDescriptor(NULL, *name, &lookup);
   if (lookup.IsField()) {
-    HCheckMaps* type_check = AddCheckMap(object, map);
-    return BuildLoadNamedField(object,
-        HObjectAccess::ForField(map, &lookup, name), type_check);
+    HCheckMaps* checked_object = AddCheckMap(object, map);
+    return BuildLoadNamedField(
+        checked_object, HObjectAccess::ForField(map, &lookup, name));
   }

   // Handle a load of a constant known function.
@@ -5462,11 +5456,10 @@
     Handle<JSObject> prototype(JSObject::cast(map->prototype()));
     Handle<JSObject> holder(lookup.holder());
     Handle<Map> holder_map(holder->map());
-    HCheckMaps* type_check = AddCheckMap(object, map);
-    BuildCheckPrototypeMaps(prototype, holder);
-    HValue* holder_value = Add<HConstant>(holder);
-    return BuildLoadNamedField(holder_value,
-        HObjectAccess::ForField(holder_map, &lookup, name), type_check);
+    AddCheckMap(object, map);
+    HValue* checked_holder = BuildCheckPrototypeMaps(prototype, holder);
+    return BuildLoadNamedField(
+ checked_holder, HObjectAccess::ForField(holder_map, &lookup, name));
   }

   // Handle a load of a constant function somewhere in the prototype chain.
@@ -5659,11 +5652,11 @@
     return is_store ? NULL : instr;
   }

-  HInstruction* checkspec =
+  HInstruction* checked_object =
       AddInstruction(HCheckInstanceType::NewIsSpecObject(object, zone()));
   HBasicBlock* join = graph()->CreateBasicBlock();

-  HInstruction* elements = AddLoadElements(object, checkspec);
+  HInstruction* elements = AddLoadElements(checked_object);

   for (int i = 0; i < untransitionable_maps.length(); ++i) {
     Handle<Map> map = untransitionable_maps[i];
@@ -5685,7 +5678,7 @@
       }
       if (map->instance_type() == JS_ARRAY_TYPE) {
         HInstruction* length = Add<HLoadNamedField>(
- object, HObjectAccess::ForArrayLength(elements_kind), mapcompare);
+            mapcompare, HObjectAccess::ForArrayLength(elements_kind));
         checked_key = Add<HBoundsCheck>(key, length);
       } else {
         HInstruction* length = AddLoadFixedArrayLength(elements);
@@ -5961,30 +5954,34 @@
 }


-void HGraphBuilder::BuildConstantMapCheck(Handle<JSObject> constant,
-                                          CompilationInfo* info) {
+HInstruction* HGraphBuilder::BuildConstantMapCheck(Handle<JSObject> constant,
+                                                   CompilationInfo* info) {
   HConstant* constant_value = New<HConstant>(constant);

   if (constant->map()->CanOmitMapChecks()) {
     constant->map()->AddDependentCompilationInfo(
         DependentCode::kPrototypeCheckGroup, info);
-    return;
+    return constant_value;
   }

   AddInstruction(constant_value);
   HCheckMaps* check =
       Add<HCheckMaps>(constant_value, handle(constant->map()), info);
   check->ClearGVNFlag(kDependsOnElementsKind);
+  return check;
 }


-void HGraphBuilder::BuildCheckPrototypeMaps(Handle<JSObject> prototype,
-                                            Handle<JSObject> holder) {
-  BuildConstantMapCheck(prototype, top_info());
+HInstruction* HGraphBuilder::BuildCheckPrototypeMaps(Handle<JSObject> prototype, + Handle<JSObject> holder) {
   while (!prototype.is_identical_to(holder)) {
+    BuildConstantMapCheck(prototype, top_info());
     prototype = handle(JSObject::cast(prototype->GetPrototype()));
-    BuildConstantMapCheck(prototype, top_info());
   }
+
+ HInstruction* checked_object = BuildConstantMapCheck(prototype, top_info());
+  if (!checked_object->IsLinked()) AddInstruction(checked_object);
+  return checked_object;
 }


=======================================
--- /branches/bleeding_edge/src/hydrogen.h      Tue Aug 20 11:10:24 2013 UTC
+++ /branches/bleeding_edge/src/hydrogen.h      Wed Aug 21 14:49:56 2013 UTC
@@ -1257,13 +1257,10 @@
       LoadKeyedHoleMode load_mode,
       KeyedAccessStoreMode store_mode);

-  HLoadNamedField* BuildLoadNamedField(
-      HValue* object,
-      HObjectAccess access,
-      HValue* typecheck);
-  HInstruction* BuildLoadStringLength(HValue* object, HValue* typecheck);
-  HStoreNamedField* AddStoreMapConstant(HValue *object, Handle<Map>);
-  HLoadNamedField* AddLoadElements(HValue *object, HValue *typecheck);
+ HLoadNamedField* BuildLoadNamedField(HValue* object, HObjectAccess access); + HInstruction* BuildLoadStringLength(HValue* object, HValue* checked_value);
+  HStoreNamedField* AddStoreMapConstant(HValue* object, Handle<Map>);
+  HLoadNamedField* AddLoadElements(HValue* object);
   HLoadNamedField* AddLoadFixedArrayLength(HValue *object);

   HValue* AddLoadJSBuiltin(Builtins::JavaScript builtin);
@@ -1549,9 +1546,10 @@
                                        int previous_object_size,
                                        HValue* payload);

- void BuildConstantMapCheck(Handle<JSObject> constant, CompilationInfo* info);
-  void BuildCheckPrototypeMaps(Handle<JSObject> prototype,
-                               Handle<JSObject> holder);
+  HInstruction* BuildConstantMapCheck(Handle<JSObject> constant,
+                                      CompilationInfo* info);
+  HInstruction* BuildCheckPrototypeMaps(Handle<JSObject> prototype,
+                                        Handle<JSObject> holder);

   HInstruction* BuildGetNativeContext();
   HInstruction* BuildGetArrayFunction();
@@ -1602,22 +1600,6 @@
   AddInstruction(instr);
   return instr;
 }
-
-
-template<>
-inline HInstruction* HGraphBuilder::NewUncasted<HLoadNamedField>(
-    HValue* object, HObjectAccess access) {
-  return NewUncasted<HLoadNamedField>(object, access,
-                                      static_cast<HValue*>(NULL));
-}
-
-
-template<>
-inline HInstruction* HGraphBuilder::AddUncasted<HLoadNamedField>(
-    HValue* object, HObjectAccess access) {
-  return AddUncasted<HLoadNamedField>(object, access,
-                                      static_cast<HValue*>(NULL));
-}


 template<>

--
--
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/groups/opt_out.

Reply via email to