Reviewers: Benedikt Meurer,

Description:
Check that environments assigned via AssignEnvironment are actually used.

Removed some temporary marker comments on the way.

Please review this at https://codereview.chromium.org/218403006/

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

Affected files (+58, -32 lines):
  M src/arm/lithium-arm.cc
  M src/arm/lithium-codegen-arm.cc
  M src/arm64/lithium-arm64.cc
  M src/arm64/lithium-codegen-arm64.cc
  M src/ia32/lithium-codegen-ia32.cc
  M src/ia32/lithium-ia32.cc
  M src/lithium.h
  M src/lithium.cc
  M src/lithium-codegen.h
  M src/lithium-codegen.cc
  M src/x64/lithium-codegen-x64.cc
  M src/x64/lithium-x64.cc


Index: src/arm/lithium-arm.cc
diff --git a/src/arm/lithium-arm.cc b/src/arm/lithium-arm.cc
index 38acd48f3c7b89f3d6d3c819689531a745fc7097..97722ccfa24876d8671978cbabfc49f5ce8fab64 100644
--- a/src/arm/lithium-arm.cc
+++ b/src/arm/lithium-arm.cc
@@ -623,6 +623,8 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
       !hinstr->HasObservableSideEffects();
   if (needs_environment && !instr->HasEnvironment()) {
     instr = AssignEnvironment(instr);
+    // We can't really figure out if the environment is needed or not.
+    instr->environment()->set_has_been_used();
   }

   return instr;
@@ -1895,10 +1897,7 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
         LOperand* temp2 = FixedTemp(d11);
         LInstruction* result =
             DefineSameAsFirst(new(zone()) LTaggedToI(value, temp1, temp2));
-        if (!val->representation().IsSmi()) {
-          // Note: Only deopts in deferred code.
-          result = AssignEnvironment(result);
-        }
+ if (!val->representation().IsSmi()) result = AssignEnvironment(result);
         return result;
       }
     }
@@ -1993,11 +1992,10 @@ LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) {
     value = UseRegisterAtStart(instr->value());
     if (instr->has_migration_target()) info()->MarkAsDeferredCalling();
   }
-  LCheckMaps* result = new(zone()) LCheckMaps(value);
+  LInstruction* result = new(zone()) LCheckMaps(value);
   if (!instr->CanOmitMapChecks()) {
-    // Note: Only deopts in deferred code.
-    AssignEnvironment(result);
-    if (instr->has_migration_target()) return AssignPointerMap(result);
+    result = AssignEnvironment(result);
+    if (instr->has_migration_target()) result = AssignPointerMap(result);
   }
   return result;
 }
Index: src/arm/lithium-codegen-arm.cc
diff --git a/src/arm/lithium-codegen-arm.cc b/src/arm/lithium-codegen-arm.cc
index 63e60ba66b00a11c106d4dee938fcdf0c316e07c..7b3788e71006efb8ba5ff9d2e80bb1c751d13d0a 100644
--- a/src/arm/lithium-codegen-arm.cc
+++ b/src/arm/lithium-codegen-arm.cc
@@ -783,6 +783,7 @@ void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id,

void LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment, Safepoint::DeoptMode mode) {
+  environment->set_has_been_used();
   if (!environment->HasBeenRegistered()) {
     // Physical stack frame layout:
     // -x ............. -4  0 ..................................... y
Index: src/arm64/lithium-arm64.cc
diff --git a/src/arm64/lithium-arm64.cc b/src/arm64/lithium-arm64.cc
index 1888affd683f74e78ebea1c6f441c0f7585c063d..d58e3cc9916bf01890c550f2b581ae158f17c71c 100644
--- a/src/arm64/lithium-arm64.cc
+++ b/src/arm64/lithium-arm64.cc
@@ -515,6 +515,8 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
       !hinstr->HasObservableSideEffects();
   if (needs_environment && !instr->HasEnvironment()) {
     instr = AssignEnvironment(instr);
+    // We can't really figure out if the environment is needed or not.
+    instr->environment()->set_has_been_used();
   }

   return instr;
@@ -1107,10 +1109,7 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) { LOperand* temp2 = instr->CanTruncateToInt32() ? NULL : FixedTemp(d24);
         LInstruction* result =
             DefineAsRegister(new(zone()) LTaggedToI(value, temp1, temp2));
-        if (!val->representation().IsSmi()) {
-          // Note: Only deopts in deferred code.
-          result = AssignEnvironment(result);
-        }
+ if (!val->representation().IsSmi()) result = AssignEnvironment(result);
         return result;
       }
     }
@@ -1194,9 +1193,8 @@ LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) {
   }
   LInstruction* result = new(zone()) LCheckMaps(value, temp);
   if (!instr->CanOmitMapChecks()) {
-    // Note: Only deopts in deferred code.
     result = AssignEnvironment(result);
-    if (instr->has_migration_target()) return AssignPointerMap(result);
+    if (instr->has_migration_target()) result = AssignPointerMap(result);
   }
   return result;
 }
@@ -2432,7 +2430,6 @@ LInstruction* LChunkBuilder::DoUnaryMathOperation(HUnaryMathOperation* instr) {
         LOperand* temp3 = TempRegister();
         LInstruction* result = DefineAsRegister(
new(zone()) LMathAbsTagged(context, input, temp1, temp2, temp3));
-        // Note: Only deopts in deferred code.
         return AssignEnvironment(AssignPointerMap(result));
       } else {
         LOperand* input = UseRegisterAtStart(instr->value());
Index: src/arm64/lithium-codegen-arm64.cc
diff --git a/src/arm64/lithium-codegen-arm64.cc b/src/arm64/lithium-codegen-arm64.cc index 9b8156e754e05d6bfb8dbf13f4e2cd91fcdf34c2..48ea7796773e0b3cb4f5638b597abd967d29f56f 100644
--- a/src/arm64/lithium-codegen-arm64.cc
+++ b/src/arm64/lithium-codegen-arm64.cc
@@ -376,6 +376,7 @@ int LCodeGen::DefineDeoptimizationLiteral(Handle<Object> literal) {

void LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment, Safepoint::DeoptMode mode) {
+  environment->set_has_been_used();
   if (!environment->HasBeenRegistered()) {
     int frame_count = 0;
     int jsframe_count = 0;
Index: src/ia32/lithium-codegen-ia32.cc
diff --git a/src/ia32/lithium-codegen-ia32.cc b/src/ia32/lithium-codegen-ia32.cc index 6c934b7ce9a7654a3b8fd6faa4238a2481f899dd..47cb2dcbf06f1cbd2b716ff7b67cb00eefc008bc 100644
--- a/src/ia32/lithium-codegen-ia32.cc
+++ b/src/ia32/lithium-codegen-ia32.cc
@@ -1051,6 +1051,7 @@ void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id,

 void LCodeGen::RegisterEnvironmentForDeoptimization(
     LEnvironment* environment, Safepoint::DeoptMode mode) {
+  environment->set_has_been_used();
   if (!environment->HasBeenRegistered()) {
     // Physical stack frame layout:
     // -x ............. -4  0 ..................................... y
Index: src/ia32/lithium-ia32.cc
diff --git a/src/ia32/lithium-ia32.cc b/src/ia32/lithium-ia32.cc
index c230deba2882abd2e16e65b9d5a76c19b5594628..66c79d1d587c2cf1857789728993c87e2cc97f43 100644
--- a/src/ia32/lithium-ia32.cc
+++ b/src/ia32/lithium-ia32.cc
@@ -688,6 +688,8 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
       !hinstr->HasObservableSideEffects();
   if (needs_environment && !instr->HasEnvironment()) {
     instr = AssignEnvironment(instr);
+    // We can't really figure out if the environment is needed or not.
+    instr->environment()->set_has_been_used();
   }

   return instr;
@@ -1934,10 +1936,7 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
                 ? FixedTemp(xmm1) : NULL;
         LInstruction* result =
             DefineSameAsFirst(new(zone()) LTaggedToI(value, xmm_temp));
-        if (!val->representation().IsSmi()) {
-          // Note: Only deopts in deferred code.
-          result = AssignEnvironment(result);
-        }
+ if (!val->representation().IsSmi()) result = AssignEnvironment(result);
         return result;
       }
     }
@@ -2043,11 +2042,10 @@ LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) {
     value = UseRegisterAtStart(instr->value());
     if (instr->has_migration_target()) info()->MarkAsDeferredCalling();
   }
-  LCheckMaps* result = new(zone()) LCheckMaps(value);
+  LInstruction* result = new(zone()) LCheckMaps(value);
   if (!instr->CanOmitMapChecks()) {
-    // Note: Only deopts in deferred code.
-    AssignEnvironment(result);
-    if (instr->has_migration_target()) return AssignPointerMap(result);
+    result = AssignEnvironment(result);
+    if (instr->has_migration_target()) result = AssignPointerMap(result);
   }
   return result;
 }
Index: src/lithium-codegen.cc
diff --git a/src/lithium-codegen.cc b/src/lithium-codegen.cc
index be0ff8371afa51ec664d61a3056d2da13ae7ff79..93ae3101a7779e50b21fe4e542334974bc75758e 100644
--- a/src/lithium-codegen.cc
+++ b/src/lithium-codegen.cc
@@ -122,6 +122,26 @@ bool LCodeGenBase::GenerateBody() {
 }


+void LCodeGenBase::CheckEnvironmentUsage() {
+#ifdef DEBUG
+  bool live_block = true;
+  for (int i = 0; i < instructions_->length(); i++) {
+    LInstruction* instr = instructions_->at(i);
+ if (instr->IsLabel()) live_block = !LLabel::cast(instr)->HasReplacement();
+    if (live_block &&
+        instr->hydrogen_value()->block()->IsReachable() &&
+        instr->HasEnvironment() &&
+        !instr->environment()->has_been_used()) {
+      FunctionLiteral* lit = info_->function();
+ V8_Fatal(__FILE__, __LINE__, "unused environment in %s <@%d,#%d> %s\n",
+               lit == NULL ? "<UNKNOWN>" : lit->name()->ToCString().get(),
+               i, instr->hydrogen_value()->id(), instr->Mnemonic());
+    }
+  }
+#endif
+}
+
+
 void LCodeGenBase::Comment(const char* format, ...) {
   if (!FLAG_code_comments) return;
   char buffer[4 * KB];
Index: src/lithium-codegen.h
diff --git a/src/lithium-codegen.h b/src/lithium-codegen.h
index 3e8d471ea78deb92f7f5647dd59cebd116f5ffd6..9f06781b852a0800b72602489a475bb2333eac58 100644
--- a/src/lithium-codegen.h
+++ b/src/lithium-codegen.h
@@ -68,6 +68,11 @@ class LCodeGenBase BASE_EMBEDDED {

   void RegisterWeakObjectsInOptimizedCode(Handle<Code> code);

+ // Check that an environment assigned via AssignEnvironment is actually being + // used. Redundant assignments keep things alive longer than necessary, and
+  // consequently lead to worse code, so it's important to minimize this.
+  void CheckEnvironmentUsage();
+
  protected:
   enum Status {
     UNUSED,
Index: src/lithium.cc
diff --git a/src/lithium.cc b/src/lithium.cc
index 8753ff14aa4f0b0cfbd1fe4b4cd6b2b151da2a20..48567930abc1c3bec19418e4e974a7fc335497d5 100644
--- a/src/lithium.cc
+++ b/src/lithium.cc
@@ -432,6 +432,7 @@ Handle<Code> LChunk::Codegen() {
   MarkEmptyBlocks();

   if (generator.GenerateCode()) {
+    generator.CheckEnvironmentUsage();
     CodeGenerator::MakeCodePrologue(info(), "optimized");
     Code::Flags flags = info()->flags();
     Handle<Code> code =
Index: src/lithium.h
diff --git a/src/lithium.h b/src/lithium.h
index 8ae5b879dc7bbe6b6f53388b8efec5011d1a89d0..161da8f0a3b6e8ecc0ee8f3cf36add6103db63a1 100644
--- a/src/lithium.h
+++ b/src/lithium.h
@@ -426,7 +426,8 @@ class LEnvironment V8_FINAL : public ZoneObject {
         object_mapping_(0, zone),
         outer_(outer),
         entry_(entry),
-        zone_(zone) { }
+        zone_(zone),
+        has_been_used_(false) { }

   Handle<JSFunction> closure() const { return closure_; }
   FrameType frame_type() const { return frame_type_; }
@@ -442,6 +443,9 @@ class LEnvironment V8_FINAL : public ZoneObject {
   HEnterInlined* entry() { return entry_; }
   Zone* zone() const { return zone_; }

+  bool has_been_used() const { return has_been_used_; }
+  void set_has_been_used() { has_been_used_ = true; }
+
   void AddValue(LOperand* operand,
                 Representation representation,
                 bool is_uint32) {
@@ -541,6 +545,7 @@ class LEnvironment V8_FINAL : public ZoneObject {
   LEnvironment* outer_;
   HEnterInlined* entry_;
   Zone* zone_;
+  bool has_been_used_;
 };


Index: src/x64/lithium-codegen-x64.cc
diff --git a/src/x64/lithium-codegen-x64.cc b/src/x64/lithium-codegen-x64.cc
index a64d3e223fae20d9f17dbb74b1580d58ed847ed3..a8536a1841f379a5078e5fc79716f16e9564024f 100644
--- a/src/x64/lithium-codegen-x64.cc
+++ b/src/x64/lithium-codegen-x64.cc
@@ -687,6 +687,7 @@ void LCodeGen::CallRuntimeFromDeferred(Runtime::FunctionId id,

void LCodeGen::RegisterEnvironmentForDeoptimization(LEnvironment* environment, Safepoint::DeoptMode mode) {
+  environment->set_has_been_used();
   if (!environment->HasBeenRegistered()) {
     // Physical stack frame layout:
     // -x ............. -4  0 ..................................... y
Index: src/x64/lithium-x64.cc
diff --git a/src/x64/lithium-x64.cc b/src/x64/lithium-x64.cc
index d1c77311ecf9da440af7748ffbf7567f6e5c78c2..90f9a1a236f72eb1b23dac9fcea4262acb986b43 100644
--- a/src/x64/lithium-x64.cc
+++ b/src/x64/lithium-x64.cc
@@ -652,6 +652,8 @@ LInstruction* LChunkBuilder::MarkAsCall(LInstruction* instr,
       !hinstr->HasObservableSideEffects();
   if (needs_environment && !instr->HasEnvironment()) {
     instr = AssignEnvironment(instr);
+    // We can't really figure out if the environment is needed or not.
+    instr->environment()->set_has_been_used();
   }

   return instr;
@@ -1857,10 +1859,7 @@ LInstruction* LChunkBuilder::DoChange(HChange* instr) {
         LOperand* xmm_temp = truncating ? NULL : FixedTemp(xmm1);
         LInstruction* result =
             DefineSameAsFirst(new(zone()) LTaggedToI(value, xmm_temp));
-        if (!val->representation().IsSmi()) {
-          // Note: Only deopts in deferred code.
-          result = AssignEnvironment(result);
-        }
+ if (!val->representation().IsSmi()) result = AssignEnvironment(result);
         return result;
       }
     }
@@ -1955,11 +1954,10 @@ LInstruction* LChunkBuilder::DoCheckMaps(HCheckMaps* instr) {
     value = UseRegisterAtStart(instr->value());
     if (instr->has_migration_target()) info()->MarkAsDeferredCalling();
   }
-  LCheckMaps* result = new(zone()) LCheckMaps(value);
+  LInstruction* result = new(zone()) LCheckMaps(value);
   if (!instr->CanOmitMapChecks()) {
-    // Note: Only deopts in deferred code.
-    AssignEnvironment(result);
-    if (instr->has_migration_target()) return AssignPointerMap(result);
+    result = AssignEnvironment(result);
+    if (instr->has_migration_target()) result = AssignPointerMap(result);
   }
   return result;
 }


--
--
v8-dev mailing list
v8-dev@googlegroups.com
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 v8-dev+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Reply via email to