Index: src/hydrogen.cc |
diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
index 33557a29f2e77314f0730606c1a0af671648984c..d38a559b06652869ef60ea04980088cca084dda3 100644 |
--- a/src/hydrogen.cc |
+++ b/src/hydrogen.cc |
@@ -989,13 +989,6 @@ void HGraphBuilder::AddSimulate(BailoutId id, |
} |
-HBoundsCheck* HGraphBuilder::AddBoundsCheck(HValue* index, HValue* length) { |
- HBoundsCheck* result = new(graph()->zone()) HBoundsCheck(index, length); |
- AddInstruction(result); |
- return result; |
-} |
- |
- |
HReturn* HGraphBuilder::AddReturn(HValue* value) { |
HValue* context = environment()->LookupContext(); |
int num_parameters = graph()->info()->num_parameters(); |
@@ -1175,7 +1168,7 @@ HValue* HGraphBuilder::BuildCheckForCapacityGrow(HValue* object, |
length_checker.Else(); |
- AddBoundsCheck(key, length); |
+ Add<HBoundsCheck>(key, length); |
environment()->Push(elements); |
length_checker.End(); |
@@ -1280,7 +1273,7 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( |
return result; |
} else { |
ASSERT(store_mode == STANDARD_STORE); |
- checked_key = AddBoundsCheck(key, length); |
+ checked_key = Add<HBoundsCheck>(key, length); |
HLoadExternalArrayPointer* external_elements = |
new(zone) HLoadExternalArrayPointer(elements); |
AddInstruction(external_elements); |
@@ -1308,7 +1301,7 @@ HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( |
length, key, is_js_array); |
checked_key = key; |
} else { |
- checked_key = AddBoundsCheck(key, length); |
+ checked_key = Add<HBoundsCheck>(key, length); |
if (is_store && (fast_elements || fast_smi_only_elements)) { |
if (store_mode == STORE_NO_TRANSITION_HANDLE_COW) { |
@@ -4663,9 +4656,9 @@ void HOptimizedGraphBuilder::PushAndAdd(HInstruction* instr) { |
} |
-void HOptimizedGraphBuilder::AddSoftDeoptimize() { |
+void HOptimizedGraphBuilder::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; |
AddInstruction(new(zone()) HSoftDeoptimize()); |
isolate()->counters()->soft_deopts_inserted()->Increment(); |
@@ -5633,9 +5626,16 @@ 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()); |
+ HConstant* constant = |
+ new(zone()) HConstant(cell->type()->AsConstant()); |
+ 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); |
@@ -6558,6 +6558,15 @@ void HOptimizedGraphBuilder::HandleGlobalVariableAssignment( |
if (type == kUseCell) { |
Handle<GlobalObject> global(current_info()->global_object()); |
Handle<PropertyCell> cell(global->GetPropertyCell(&lookup)); |
+ if (cell->type()->IsConstant()) { |
+ IfBuilder builder(this); |
+ HValue* constant = Add<HConstant>(cell->type()->AsConstant()); |
+ builder.If<HCompareObjectEqAndBranch>(value, constant); |
+ builder.Then(); |
+ builder.Else(); |
+ AddSoftDeoptimize(MUST_EMIT_SOFT_DEOPT); |
+ builder.End(); |
+ } |
HInstruction* instr = |
new(zone()) HStoreGlobalCell(value, cell, lookup.GetPropertyDetails()); |
instr->set_position(position); |
@@ -7296,7 +7305,7 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( |
&& todo_external_array) { |
HInstruction* length = |
AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); |
- checked_key = AddBoundsCheck(key, length); |
+ checked_key = Add<HBoundsCheck>(key, length); |
external_elements = new(zone()) HLoadExternalArrayPointer(elements); |
AddInstruction(external_elements); |
} |
@@ -7339,7 +7348,7 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( |
typecheck, Representation::Smi()); |
length->set_type(HType::Smi()); |
- checked_key = AddBoundsCheck(key, length); |
+ checked_key = Add<HBoundsCheck>(key, length); |
access = AddInstruction(BuildFastElementAccess( |
elements, checked_key, val, elements_kind_branch, |
elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE)); |
@@ -7357,7 +7366,7 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess( |
set_current_block(if_fastobject); |
length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); |
- checked_key = AddBoundsCheck(key, length); |
+ checked_key = Add<HBoundsCheck>(key, length); |
access = AddInstruction(BuildFastElementAccess( |
elements, checked_key, val, elements_kind_branch, |
elements_kind, is_store, NEVER_RETURN_HOLE, STANDARD_STORE)); |
@@ -7509,7 +7518,7 @@ bool HOptimizedGraphBuilder::TryArgumentsAccess(Property* expr) { |
new(zone()) HArgumentsElements(false)); |
HInstruction* length = AddInstruction( |
new(zone()) HArgumentsLength(elements)); |
- HInstruction* checked_key = AddBoundsCheck(key, length); |
+ HInstruction* checked_key = Add<HBoundsCheck>(key, length); |
result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); |
} else { |
EnsureArgumentsArePushedForAccess(); |
@@ -7520,7 +7529,7 @@ bool HOptimizedGraphBuilder::TryArgumentsAccess(Property* expr) { |
arguments_environment()->parameter_count() - 1; |
HInstruction* length = AddInstruction(new(zone()) HConstant( |
argument_count)); |
- HInstruction* checked_key = AddBoundsCheck(key, length); |
+ HInstruction* checked_key = Add<HBoundsCheck>(key, length); |
result = new(zone()) HAccessArgumentsAt(elements, length, checked_key); |
} |
} |
@@ -8899,7 +8908,7 @@ void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) { |
Handle<Cell> cell = expr->allocation_info_cell(); |
AddInstruction(new(zone()) HCheckFunction(constructor, array_function)); |
call = new(zone()) HCallNewArray(context, constructor, argument_count, |
- cell); |
+ cell, expr->elements_kind()); |
} else { |
call = new(zone()) HCallNew(context, constructor, argument_count); |
} |
@@ -9349,7 +9358,7 @@ HInstruction* HOptimizedGraphBuilder::BuildStringCharCodeAt( |
AddInstruction(HCheckInstanceType::NewIsString(string, zone())); |
HInstruction* length = HStringLength::New(zone(), string); |
AddInstruction(length); |
- HInstruction* checked_index = AddBoundsCheck(index, length); |
+ HInstruction* checked_index = Add<HBoundsCheck>(index, length); |
return new(zone()) HStringCharCodeAt(context, string, checked_index); |
} |
@@ -10004,10 +10013,22 @@ void HOptimizedGraphBuilder::BuildEmitDeepCopy( |
} |
// Copy in-object properties. |
- HValue* object_properties = |
- AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset)); |
- BuildEmitInObjectProperties(boilerplate_object, original_boilerplate_object, |
- object_properties, target, offset); |
+ Handle<DescriptorArray> descriptors( |
+ boilerplate_object->map()->instance_descriptors()); |
+ int descriptor_count = boilerplate_object->map()->NumberOfOwnDescriptors(); |
+ bool has_field = false; |
+ for (int i = 0; i < descriptor_count; i++) { |
+ PropertyDetails details = descriptors->GetDetails(i); |
+ if (details.type() != FIELD) continue; |
+ has_field = true; |
+ } |
+ |
+ if (has_field) { |
+ HValue* object_properties = |
+ AddInstruction(new(zone) HInnerAllocatedObject(target, object_offset)); |
+ BuildEmitInObjectProperties(boilerplate_object, original_boilerplate_object, |
+ object_properties, target, offset); |
+ } |
// Create allocation site info. |
if (mode == TRACK_ALLOCATION_SITE && |
@@ -10516,7 +10537,7 @@ void HOptimizedGraphBuilder::GenerateArguments(CallRuntime* call) { |
HInstruction* elements = AddInstruction( |
new(zone()) HArgumentsElements(false)); |
HInstruction* length = AddInstruction(new(zone()) HArgumentsLength(elements)); |
- HInstruction* checked_index = AddBoundsCheck(index, length); |
+ HInstruction* checked_index = Add<HBoundsCheck>(index, length); |
HAccessArgumentsAt* result = |
new(zone()) HAccessArgumentsAt(elements, length, checked_index); |
return ast_context()->ReturnInstruction(result, call->id()); |