};
-class HDeoptimize: public HTemplateControlInstruction<0> {
+class HDeoptimize: public HControlInstruction {
public:
- HDeoptimize() : HTemplateControlInstruction<0>(NULL, NULL) { }
+ HDeoptimize(int environment_length)
+ : HControlInstruction(NULL, NULL),
+ values_(environment_length) { }
virtual Representation RequiredInputRepresentation(int index) const {
return Representation::None();
}
+ virtual int OperandCount() { return values_.length(); }
+ virtual HValue* OperandAt(int index) { return values_[index]; }
+
+ void AddEnvironmentValue(HValue* value) {
+ values_.Add(NULL);
+ SetOperandAt(values_.length() - 1, value);
+ }
+
DECLARE_CONCRETE_INSTRUCTION(Deoptimize, "deoptimize")
+
+ protected:
+ virtual void InternalSetOperandAt(int index, HValue* value) {
+ values_[index] = value;
+ }
+
+ private:
+ ZoneList<HValue*> values_;
};
}
+HDeoptimize* HBasicBlock::CreateDeoptimize() {
+ ASSERT(HasEnvironment());
+ HEnvironment* environment = last_environment();
+
+ HDeoptimize* instr = new HDeoptimize(environment->length());
+
+ for (int i = 0; i < environment->length(); i++) {
+ HValue* val = environment->values()->at(i);
+ instr->AddEnvironmentValue(val);
+ }
+
+ return instr;
+}
+
+
HSimulate* HBasicBlock::CreateSimulate(int id) {
ASSERT(HasEnvironment());
HEnvironment* environment = last_environment();
}
VISIT_FOR_VALUE(stmt->tag());
+ AddSimulate(stmt->EntryId());
HValue* tag_value = Pop();
HBasicBlock* first_test_block = current_block();
// Unconditionally deoptimize on the first non-smi compare.
clause->RecordTypeFeedback(oracle());
if (!clause->IsSmiCompare()) {
- if (current_block() == first_test_block) {
- // If the first test is the one that deopts and if the tag value is
- // a phi, we need to have some use of that phi to prevent phi
- // elimination from removing it. This HSimulate is such a use.
- Push(tag_value);
- AddSimulate(stmt->EntryId());
- Drop(1);
- }
- current_block()->Finish(new HDeoptimize());
+ current_block()->FinishExitWithDeoptimization();
set_current_block(NULL);
break;
}
// know about and do not want to handle ones we've never seen. Otherwise
// use a generic IC.
if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
- current_block()->FinishExit(new HDeoptimize);
+ current_block()->FinishExitWithDeoptimization();
} else {
HInstruction* instr = BuildStoreNamedGeneric(object, name, value);
instr->set_position(expr->position());
// know about and do not want to handle ones we've never seen. Otherwise
// use a generic IC.
if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
- current_block()->FinishExit(new HDeoptimize);
+ current_block()->FinishExitWithDeoptimization();
} else {
HInstruction* instr = BuildLoadNamedGeneric(object, expr);
instr->set_position(expr->position());
// know about and do not want to handle ones we've never seen. Otherwise
// use a generic IC.
if (count == types->length() && FLAG_deoptimize_uncommon_cases) {
- current_block()->FinishExit(new HDeoptimize);
+ current_block()->FinishExitWithDeoptimization();
} else {
HContext* context = new HContext;
AddInstruction(context);
void AddSimulate(int id) { AddInstruction(CreateSimulate(id)); }
void AssignCommonDominator(HBasicBlock* other);
+ void FinishExitWithDeoptimization() {
+ FinishExit(CreateDeoptimize());
+ }
+
// Add the inlined function exit sequence, adding an HLeaveInlined
// instruction and updating the bailout environment.
void AddLeaveInlined(HValue* return_value, HBasicBlock* target);
void AddDominatedBlock(HBasicBlock* block);
HSimulate* CreateSimulate(int id);
+ HDeoptimize* CreateDeoptimize();
int block_id_;
HGraph* graph_;
--- /dev/null
+// Copyright 2011 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+// * Redistributions of source code must retain the above copyright
+// notice, this list of conditions and the following disclaimer.
+// * Redistributions in binary form must reproduce the above
+// copyright notice, this list of conditions and the following
+// disclaimer in the documentation and/or other materials provided
+// with the distribution.
+// * Neither the name of Google Inc. nor the names of its
+// contributors may be used to endorse or promote products derived
+// from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+function g(y) { assertEquals(y, 12); }
+
+var X = 0;
+
+function foo () {
+ var cnt = 0;
+ var l = -1;
+ var x = 0;
+ while (1) switch (l) {
+ case -1:
+ var y = x + 12;
+ l = 0;
+ break;
+ case 0:
+ // Loop for to hit OSR.
+ if (cnt++ < 10000000) {
+ l = 0;
+ break;
+ } else {
+ l = 1;
+ break;
+ }
+ case 1:
+ // This case will contain deoptimization
+ // because it has no type feedback.
+ g(y);
+ return;
+ };
+}
+
+foo();