Reviewers: Michael Starzinger, Toon Verwaest,

Message:
Please take a preliminary look, for now only ia32 arch.

This is based on https://chromiumcodereview.appspot.com/12224035/

Is lithium a good place to remove the check, or is it better to do on hydrogen
level by adjusting HCheckPrototypeMaps?

Description:
Remove prototype checks for leaf maps in optimized code.


Please review this at https://chromiumcodereview.appspot.com/12225099/

SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M src/ia32/lithium-codegen-ia32.h
  M src/ia32/lithium-codegen-ia32.cc
  M src/objects.h
  M src/objects.cc


Index: src/ia32/lithium-codegen-ia32.cc
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index dfced7c221335f060f7c333e02c0ec38bb7516d8..94bba205320002dff531c9356bd87a3d96e87310 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -5332,9 +5332,21 @@ void LCodeGen::DoCheckPrototypeMaps(LCheckPrototypeMaps* instr) {

   ASSERT(prototypes->length() == maps->length());

-  for (int i = 0; i < prototypes->length(); i++) {
-    __ LoadHeapObject(reg, prototypes->at(i));
- DoCheckMapCommon(reg, maps->at(i), ALLOW_ELEMENT_TRANSITION_MAPS, instr);
+  bool can_ommit_checks = true;
+  for (int i = 0; i < maps->length() && can_ommit_checks; i++) {
+    if (maps->at(i)->HasTransitionArray()) can_ommit_checks = false;
+    if (maps->at(i)->is_dictionary_map()) can_ommit_checks = false;
+  }
+  if (can_ommit_checks) {
+      for (int i = 0; i < maps->length(); i++) {
+      prototype_maps_.Add(maps->at(i), info()->zone());
+    }
+    __ LoadHeapObject(reg, prototypes->at(prototypes->length() - 1));
+  } else {
+    for (int i = 0; i < prototypes->length(); i++) {
+      __ LoadHeapObject(reg, prototypes->at(i));
+ DoCheckMapCommon(reg, maps->at(i), ALLOW_ELEMENT_TRANSITION_MAPS, instr);
+    }
   }
 }

Index: src/ia32/lithium-codegen-ia32.h
diff --git a/src/ia32/lithium-codegen-ia32.h b/src/ia32/lithium-codegen-ia32.h index 283430524c545eb39e22f7a6882f65e51bf2ef7b..6049257cbdf7e5a6704916376388c3e10f009852 100644
--- a/src/ia32/lithium-codegen-ia32.h
+++ b/src/ia32/lithium-codegen-ia32.h
@@ -57,6 +57,7 @@ class LCodeGen BASE_EMBEDDED {
         deoptimizations_(4, info->zone()),
         jump_table_(4, info->zone()),
         deoptimization_literals_(8, info->zone()),
+        prototype_maps_(0, info->zone()),
         inlined_function_count_(0),
         scope_(info->scope()),
         status_(UNUSED),
@@ -394,6 +395,7 @@ class LCodeGen BASE_EMBEDDED {
   ZoneList<LEnvironment*> deoptimizations_;
   ZoneList<JumpTableEntry> jump_table_;
   ZoneList<Handle<Object> > deoptimization_literals_;
+  ZoneList<Handle<Map> > prototype_maps_;
   int inlined_function_count_;
   Scope* const scope_;
   Status status_;
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index a72585d696948c827a1659fb0d0c201003b9ac11..4a38c1f43141944dd82a4be3f458d1d8f4aa8fb2 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -3624,6 +3624,7 @@ MaybeObject* JSObject::NormalizeProperties(PropertyNormalizationMode mode,
   }

   set_map(new_map);
+ map_of_this->DeoptimizeDependentCodes(DependentCodes::kPrototypeCheckGroup);

   set_properties(dictionary);

@@ -5292,6 +5293,7 @@ MaybeObject* Map::CopyDropDescriptors() {
result->set_pre_allocated_property_fields(pre_allocated_property_fields());
   result->set_is_shared(false);
   result->ClearCodeCache(GetHeap());
+  DeoptimizeDependentCodes(DependentCodes::kPrototypeCheckGroup);
   return result;
 }

@@ -9555,6 +9557,37 @@ bool DependentCodes::Contains(DependencyGroup group, Code* code) {
   return false;
 }

+class DeoptimizeDependentCodeFilter : public OptimizedFunctionFilter {
+ public:
+  virtual bool TakeFunction(JSFunction* function) {
+    return function->code()->marked_for_deoptimization();
+  }
+};
+
+
+void Map::DeoptimizeDependentCodes(DependentCodes::DependencyGroup group) {
+  AssertNoAllocation no_allocation_scope;
+  DependentCodes* codes = dependent_codes();
+  DependentCodes::GroupStartIndexes starts;
+  codes->ComputeGroupStartIndexes(starts);
+  int start = starts[group];
+  int end = starts[group + 1];
+  int number_of_codes = starts[DependentCodes::kGroupCount];
+  if (start == end) return;
+  for (int i = start; i < end; i++) {
+    Code* code = codes->code_at(i);
+    if (!code->marked_for_deoptimization()) {
+      code->set_marked_for_deoptimization(true);
+    }
+  }
+  for (int src = end, dst = start; src < number_of_codes; src++, dst++) {
+    codes->set_code_at(dst, codes->code_at(src));
+  }
+  codes->set_number_of_codes(group, 0);
+  DeoptimizeDependentCodeFilter filter;
+  Deoptimizer::DeoptimizeAllFunctionsWith(&filter);
+}
+

 MaybeObject* JSReceiver::SetPrototype(Object* value,
                                       bool skip_hidden_prototypes) {
Index: src/objects.h
diff --git a/src/objects.h b/src/objects.h
index 1f6e7cc0878c87a8630b77f4e05bd40f7d89cc18..130d3a54d9336e426edb36ca06001170b85ce341 100644
--- a/src/objects.h
+++ b/src/objects.h
@@ -4706,7 +4706,10 @@ class DependentCodes: public FixedArray {
     // Group of codes that weakly embed this map and depend on being
     // deoptimized when the map is garbage collected.
     kWeaklyEmbeddedGroup,
-    kGroupCount = kWeaklyEmbeddedGroup + 1
+ // Group of codes that omitted prototype check for a prototype with this map
+    // and depend on being deoptimized when map layout changes.
+    kPrototypeCheckGroup,
+    kGroupCount = kPrototypeCheckGroup + 1
   };
   // Array for holding the index of the first code object of each group.
   // The last element stores the total number of code objects.
@@ -5182,6 +5185,8 @@ class Map: public HeapObject {
   inline void AddDependentCode(DependentCodes::DependencyGroup group,
                                Handle<Code> code);

+  void DeoptimizeDependentCodes(DependentCodes::DependencyGroup group);
+
   // Dispatched behavior.
   DECLARE_PRINTER(Map)
   DECLARE_VERIFIER(Map)


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