Index: src/hydrogen.cc |
diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
index 98c1d85db50e46b5017219b65c9fad4968ed2b04..66e8a248dd0c80b0c20bba6f692a4c51fa1bd1ab 100644 |
--- a/src/hydrogen.cc |
+++ b/src/hydrogen.cc |
@@ -1,4 +1,4 @@ |
-// Copyright 2012 the V8 project authors. All rights reserved. |
+// Copyright 2013 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: |
@@ -649,6 +649,7 @@ HConstant* HGraph::GetConstant##Name() { \ |
htype, \ |
false, \ |
true, \ |
+ false, \ |
boolean_value); \ |
constant->InsertAfter(GetConstantUndefined()); \ |
constant_##name##_.set(constant); \ |
@@ -671,6 +672,19 @@ HConstant* HGraph::GetInvalidContext() { |
} |
+bool HGraph::IsStandardConstant(HConstant* constant) { |
+ if (constant == GetConstantUndefined()) return true; |
+ if (constant == GetConstant0()) return true; |
+ if (constant == GetConstant1()) return true; |
+ if (constant == GetConstantMinus1()) return true; |
+ if (constant == GetConstantTrue()) return true; |
+ if (constant == GetConstantFalse()) return true; |
+ if (constant == GetConstantHole()) return true; |
+ if (constant == GetConstantNull()) return true; |
+ return false; |
+} |
+ |
+ |
HGraphBuilder::IfBuilder::IfBuilder(HGraphBuilder* builder, int position) |
: builder_(builder), |
position_(position), |
@@ -1005,9 +1019,9 @@ HReturn* HGraphBuilder::AddReturn(HValue* value) { |
} |
-void HGraphBuilder::AddSoftDeoptimize() { |
+void HGraphBuilder::AddSoftDeoptimize(SoftDeoptimizeMode mode) { |
isolate()->counters()->soft_deopts_requested()->Increment(); |
- if (FLAG_always_opt) return; |
+ if (FLAG_always_opt && mode == CAN_OMIT_SOFT_DEOPT) return; |
if (current_block()->IsDeoptimizing()) return; |
Add<HSoftDeoptimize>(); |
isolate()->counters()->soft_deopts_inserted()->Increment(); |
@@ -4998,9 +5012,20 @@ void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { |
if (type == kUseCell) { |
Handle<GlobalObject> global(current_info()->global_object()); |
Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); |
- HLoadGlobalCell* instr = |
- new(zone()) HLoadGlobalCell(cell, lookup.GetPropertyDetails()); |
- return ast_context()->ReturnInstruction(instr, expr->id()); |
+ if (cell->type()->IsConstant()) { |
+ cell->AddDependentCompilationInfo(top_info()); |
+ Handle<Object> constant_object = cell->type()->AsConstant(); |
+ if (constant_object->IsConsString()) { |
+ constant_object = |
+ FlattenGetString(Handle<String>::cast(constant_object)); |
+ } |
+ HConstant* constant = new(zone()) HConstant(constant_object); |
+ return ast_context()->ReturnInstruction(constant, expr->id()); |
+ } else { |
+ HLoadGlobalCell* instr = |
+ new(zone()) HLoadGlobalCell(cell, lookup.GetPropertyDetails()); |
+ return ast_context()->ReturnInstruction(instr, expr->id()); |
+ } |
} else { |
HValue* context = environment()->LookupContext(); |
HGlobalObject* global_object = new(zone()) HGlobalObject(context); |
@@ -5911,8 +5936,21 @@ void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( |
if (type == kUseCell) { |
Handle<GlobalObject> global(current_info()->global_object()); |
Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); |
- HInstruction* instr = Add<HStoreGlobalCell>(value, cell, |
- lookup.GetPropertyDetails()); |
+ if (cell->type()->IsConstant()) { |
+ IfBuilder builder(this); |
+ HValue* constant = Add<HConstant>(cell->type()->AsConstant()); |
+ if (cell->type()->AsConstant()->IsNumber()) { |
+ builder.IfCompare(value, constant, Token::EQ); |
+ } else { |
+ builder.If<HCompareObjectEqAndBranch>(value, constant); |
+ } |
+ builder.Then(); |
+ builder.Else(); |
+ AddSoftDeoptimize(MUST_EMIT_SOFT_DEOPT); |
+ builder.End(); |
+ } |
+ HInstruction* instr = |
+ Add<HStoreGlobalCell>(value, cell, lookup.GetPropertyDetails()); |
instr->set_position(position); |
if (instr->HasObservableSideEffects()) { |
AddSimulate(ast_id, REMOVABLE_SIMULATE); |