Chromium Code Reviews| Index: src/hydrogen.cc |
| diff --git a/src/hydrogen.cc b/src/hydrogen.cc |
| index 0a25bb039ae0ffeb4d62ee77fa6d8fbca69484f0..596be03d0e1a2fbbbb546d12c295a3decb2e8480 100644 |
| --- a/src/hydrogen.cc |
| +++ b/src/hydrogen.cc |
| @@ -29,6 +29,7 @@ |
| #include "hydrogen.h" |
| #include "codegen.h" |
| +#include "elements-hydrogen.h" |
|
Jakob Kummerow
2012/11/19 12:36:00
remove
danno
2012/11/26 17:16:18
Done.
|
| #include "full-codegen.h" |
| #include "hashmap.h" |
| #include "lithium-allocator.h" |
| @@ -137,6 +138,7 @@ HSimulate* HBasicBlock::CreateSimulate(BailoutId ast_id) { |
| ASSERT(HasEnvironment()); |
| HEnvironment* environment = last_environment(); |
| ASSERT(ast_id.IsNone() || |
| + ast_id == BailoutId::StubEntry() || |
| environment->closure()->shared()->VerifyBailoutId(ast_id)); |
| int push_count = environment->push_count(); |
| @@ -275,7 +277,8 @@ void HBasicBlock::RegisterPredecessor(HBasicBlock* pred) { |
| } |
| } else if (!HasEnvironment() && !IsFinished()) { |
| ASSERT(!IsLoopHeader()); |
| - SetInitialEnvironment(pred->last_environment()->Copy()); |
| + HEnvironment* last = pred->last_environment(); |
|
Jakob Kummerow
2012/11/19 12:36:00
remove this change?
danno
2012/11/26 17:16:18
Done.
|
| + SetInitialEnvironment(last->Copy()); |
| } |
| predecessors_.Add(pred, zone()); |
| @@ -698,8 +701,13 @@ HGraph::HGraph(CompilationInfo* info) |
| is_recursive_(false), |
| use_optimistic_licm_(false), |
| type_change_checksum_(0) { |
| - start_environment_ = |
| - new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); |
| + if (info->IsStub()) { |
| + start_environment_ = |
| + new(zone_) HEnvironment(zone_); |
| + } else { |
| + start_environment_ = |
| + new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); |
| + } |
| start_environment_->set_ast_id(BailoutId::FunctionEntry()); |
| entry_block_ = CreateBasicBlock(); |
| entry_block_->SetInitialEnvironment(start_environment_); |
| @@ -725,7 +733,6 @@ void HGraph::Canonicalize() { |
| } |
| } |
| } |
| - |
| // Block ordering was implemented with two mutually recursive methods, |
| // HGraph::Postorder and HGraph::PostorderLoopBlocks. |
| // The recursion could lead to stack overflow so the algorithm has been |
| @@ -6031,18 +6038,29 @@ HInstruction* HGraphBuilder::BuildLoadKeyedGeneric(HValue* object, |
| } |
| +static HInstruction* AddBlockInstruction(HBasicBlock* current_block, |
| + HInstruction* instr) { |
| + ASSERT(current_block != NULL); |
| + current_block->AddInstruction(instr); |
| + return instr; |
| +} |
| + |
| + |
| HInstruction* HGraphBuilder::BuildExternalArrayElementAccess( |
| + HGraph* graph, |
| + HBasicBlock* current_block, |
| HValue* external_elements, |
| HValue* checked_key, |
| HValue* val, |
| HValue* dependency, |
| ElementsKind elements_kind, |
| - bool is_store) { |
| + bool is_store, |
| + Zone* zone) { |
| if (is_store) { |
| ASSERT(val != NULL); |
| switch (elements_kind) { |
| case EXTERNAL_PIXEL_ELEMENTS: { |
| - val = AddInstruction(new(zone()) HClampToUint8(val)); |
| + val = AddBlockInstruction(current_block, new(zone) HClampToUint8(val)); |
| break; |
| } |
| case EXTERNAL_BYTE_ELEMENTS: |
| @@ -6052,7 +6070,7 @@ HInstruction* HGraphBuilder::BuildExternalArrayElementAccess( |
| case EXTERNAL_INT_ELEMENTS: |
| case EXTERNAL_UNSIGNED_INT_ELEMENTS: { |
| if (!val->representation().IsInteger32()) { |
| - val = AddInstruction(new(zone()) HChange( |
| + val = AddBlockInstruction(current_block, new(zone) HChange( |
| val, |
| Representation::Integer32(), |
| true, // Truncate to int32. |
| @@ -6074,54 +6092,56 @@ HInstruction* HGraphBuilder::BuildExternalArrayElementAccess( |
| UNREACHABLE(); |
| break; |
| } |
| - return new(zone()) HStoreKeyed(external_elements, |
| - checked_key, |
| - val, |
| - elements_kind); |
| + return new(zone) HStoreKeyed(external_elements, |
| + checked_key, |
|
Jakob Kummerow
2012/11/19 12:36:00
nit: indentation
danno
2012/11/26 17:16:18
Done.
|
| + val, |
| + elements_kind); |
| } else { |
| ASSERT(val == NULL); |
| HLoadKeyed* load = |
| - new(zone()) HLoadKeyed( |
| + new(zone) HLoadKeyed( |
| external_elements, checked_key, dependency, elements_kind); |
| if (FLAG_opt_safe_uint32_operations && |
| elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) { |
| - graph()->RecordUint32Instruction(load); |
| + graph->RecordUint32Instruction(load); |
| } |
| return load; |
| } |
| } |
| -HInstruction* HGraphBuilder::BuildFastElementAccess(HValue* elements, |
| +HInstruction* HGraphBuilder::BuildFastElementAccess(HGraph* graph, |
| + HBasicBlock* current_block, |
| + HValue* elements, |
| HValue* checked_key, |
| HValue* val, |
| HValue* load_dependency, |
| ElementsKind elements_kind, |
| - bool is_store) { |
| + bool is_store, |
| + Zone* zone) { |
| if (is_store) { |
| ASSERT(val != NULL); |
| switch (elements_kind) { |
| case FAST_SMI_ELEMENTS: |
| case FAST_HOLEY_SMI_ELEMENTS: |
| // Smi-only arrays need a smi check. |
| - AddInstruction(new(zone()) HCheckSmi(val)); |
| + AddBlockInstruction(current_block, new(zone) HCheckSmi(val)); |
| // Fall through. |
| case FAST_ELEMENTS: |
| case FAST_HOLEY_ELEMENTS: |
| case FAST_DOUBLE_ELEMENTS: |
| case FAST_HOLEY_DOUBLE_ELEMENTS: |
| - return new(zone()) HStoreKeyed( |
| - elements, checked_key, val, elements_kind); |
| + return new(zone) HStoreKeyed(elements, checked_key, val, elements_kind); |
| default: |
| UNREACHABLE(); |
| return NULL; |
| } |
| } |
| // It's an element load (!is_store). |
| - return new(zone()) HLoadKeyed(elements, |
| - checked_key, |
| - load_dependency, |
| - elements_kind); |
| + return new(zone) HLoadKeyed(elements, |
| + checked_key, |
| + load_dependency, |
| + elements_kind); |
| } |
| @@ -6137,64 +6157,80 @@ HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object, |
| if (dependency) { |
| mapcheck->ClearGVNFlag(kDependsOnElementsKind); |
| } |
| - return BuildUncheckedMonomorphicElementAccess(object, key, val, |
| - mapcheck, map, is_store); |
| + return BuildUncheckedMonomorphicElementAccess( |
| + graph(), |
| + current_block(), object, key, val, |
| + mapcheck, map->instance_type() == JS_ARRAY_TYPE, |
| + map->elements_kind(), is_store, zone()); |
| } |
| HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( |
| + HGraph* graph, |
| + HBasicBlock* current_block, |
| HValue* object, |
| HValue* key, |
| HValue* val, |
| HCheckMaps* mapcheck, |
| - Handle<Map> map, |
| - bool is_store) { |
| + bool is_js_array, |
| + ElementsKind elements_kind, |
| + bool is_store, |
| + Zone* zone) { |
| // No GVNFlag is necessary for ElementsKind if there is an explicit dependency |
| // on a HElementsTransition instruction. The flag can also be removed if the |
| // map to check has FAST_HOLEY_ELEMENTS, since there can be no further |
| // ElementsKind transitions. Finally, the dependency can be removed for stores |
| // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the |
| // generated store code. |
| - if ((map->elements_kind() == FAST_HOLEY_ELEMENTS) || |
| - (map->elements_kind() == FAST_ELEMENTS && is_store)) { |
| - mapcheck->ClearGVNFlag(kDependsOnElementsKind); |
| + if ((elements_kind == FAST_HOLEY_ELEMENTS) || |
| + (elements_kind == FAST_ELEMENTS && is_store)) { |
| + if (mapcheck != NULL) { |
| + mapcheck->ClearGVNFlag(kDependsOnElementsKind); |
| + } |
| } |
| - bool fast_smi_only_elements = map->has_fast_smi_elements(); |
| - bool fast_elements = map->has_fast_object_elements(); |
| + bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind); |
| + bool fast_elements = IsFastObjectElementsKind(elements_kind); |
| HInstruction* elements = |
| - AddInstruction(new(zone()) HLoadElements(object, mapcheck)); |
| + AddBlockInstruction(current_block, |
| + new(zone) HLoadElements(object, mapcheck)); |
| if (is_store && (fast_elements || fast_smi_only_elements)) { |
| - HCheckMaps* check_cow_map = new(zone()) HCheckMaps( |
| - elements, isolate()->factory()->fixed_array_map(), zone()); |
| + HCheckMaps* check_cow_map = new(zone) HCheckMaps( |
| + elements, Isolate::Current()->factory()->fixed_array_map(), zone); |
| check_cow_map->ClearGVNFlag(kDependsOnElementsKind); |
| - AddInstruction(check_cow_map); |
| + AddBlockInstruction(current_block, check_cow_map); |
| } |
| HInstruction* length = NULL; |
| HInstruction* checked_key = NULL; |
| - if (map->has_external_array_elements()) { |
| - length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); |
| - checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length, |
| - ALLOW_SMI_KEY)); |
| + if (IsExternalArrayElementsKind(elements_kind)) { |
| + length = AddBlockInstruction(current_block, |
| + new(zone) HFixedArrayBaseLength(elements)); |
| + checked_key = AddBlockInstruction(current_block, |
| + new(zone) HBoundsCheck(key, length, |
| + ALLOW_SMI_KEY)); |
| HLoadExternalArrayPointer* external_elements = |
| - new(zone()) HLoadExternalArrayPointer(elements); |
| - AddInstruction(external_elements); |
| - return BuildExternalArrayElementAccess( |
| - external_elements, checked_key, val, mapcheck, |
| - map->elements_kind(), is_store); |
| + new(zone) HLoadExternalArrayPointer(elements); |
| + AddBlockInstruction(current_block, external_elements); |
| + return BuildExternalArrayElementAccess(graph, |
| + current_block, external_elements, checked_key, val, mapcheck, |
| + elements_kind, is_store, zone); |
| } |
| ASSERT(fast_smi_only_elements || |
| fast_elements || |
| - map->has_fast_double_elements()); |
| - if (map->instance_type() == JS_ARRAY_TYPE) { |
| - length = AddInstruction(new(zone()) HJSArrayLength(object, mapcheck, |
| - HType::Smi())); |
| + IsFastDoubleElementsKind(elements_kind)); |
| + if (is_js_array) { |
| + length = AddBlockInstruction(current_block, |
| + new(zone) HJSArrayLength(object, mapcheck, |
| + HType::Smi())); |
| } else { |
| - length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); |
| + length = AddBlockInstruction(current_block, |
| + new(zone) HFixedArrayBaseLength(elements)); |
| } |
| - checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length, |
| - ALLOW_SMI_KEY)); |
| - return BuildFastElementAccess(elements, checked_key, val, mapcheck, |
| - map->elements_kind(), is_store); |
| + checked_key = AddBlockInstruction(current_block, |
| + new(zone) HBoundsCheck(key, length, |
| + ALLOW_SMI_KEY)); |
| + return BuildFastElementAccess(graph, current_block, |
| + elements, checked_key, val, mapcheck, |
| + elements_kind, is_store, zone); |
| } |
| @@ -6246,7 +6282,11 @@ HInstruction* HGraphBuilder::TryBuildConsolidatedElementLoad( |
| HCheckMaps* check_maps = new(zone()) HCheckMaps(object, maps, zone()); |
| AddInstruction(check_maps); |
| HInstruction* instr = BuildUncheckedMonomorphicElementAccess( |
| - object, key, val, check_maps, most_general_consolidated_map, false); |
| + graph(), |
| + current_block(), object, key, val, check_maps, |
| + most_general_consolidated_map->instance_type() == JS_ARRAY_TYPE, |
| + most_general_consolidated_map->elements_kind(), |
| + false, zone()); |
| return instr; |
| } |
| @@ -6416,8 +6456,9 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object, |
| checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length, |
| ALLOW_SMI_KEY)); |
| access = AddInstruction(BuildFastElementAccess( |
| - elements, checked_key, val, elements_kind_branch, |
| - elements_kind, is_store)); |
| + graph(), |
| + current_block(), elements, checked_key, val, elements_kind_branch, |
| + elements_kind, is_store, zone())); |
| if (!is_store) { |
| Push(access); |
| } |
| @@ -6433,8 +6474,10 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object, |
| checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length, |
| ALLOW_SMI_KEY)); |
| access = AddInstruction(BuildFastElementAccess( |
| + graph(), |
| + current_block(), |
| elements, checked_key, val, elements_kind_branch, |
| - elements_kind, is_store)); |
| + elements_kind, is_store, zone())); |
| } else if (elements_kind == DICTIONARY_ELEMENTS) { |
| if (is_store) { |
| access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); |
| @@ -6443,8 +6486,10 @@ HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object, |
| } |
| } else { // External array elements. |
| access = AddInstruction(BuildExternalArrayElementAccess( |
| - external_elements, checked_key, val, elements_kind_branch, |
| - elements_kind, is_store)); |
| + graph(), |
| + current_block(), external_elements, checked_key, val, |
| + elements_kind_branch, |
| + elements_kind, is_store, zone())); |
| } |
| *has_side_effects |= access->HasObservableSideEffects(); |
| if (position != RelocInfo::kNoPosition) access->set_position(position); |
| @@ -9490,6 +9535,23 @@ HEnvironment::HEnvironment(HEnvironment* outer, |
| } |
| +HEnvironment::HEnvironment(Zone* zone) |
| + : values_(0, zone), |
| + assigned_variables_(0, zone), |
| + frame_type_(STUB), |
| + parameter_count_(0), |
| + specials_count_(0), |
| + local_count_(0), |
| + outer_(NULL), |
| + entry_(NULL), |
| + pop_count_(0), |
| + push_count_(0), |
| + ast_id_(BailoutId::None()), |
| + zone_(zone) { |
| + Initialize(0, 0, 0); |
| +} |
| + |
| + |
| HEnvironment::HEnvironment(const HEnvironment* other, Zone* zone) |
| : values_(0, zone), |
| assigned_variables_(0, zone), |
| @@ -9757,11 +9819,16 @@ void HEnvironment::PrintToStd() { |
| } |
| -void HTracer::TraceCompilation(FunctionLiteral* function) { |
| +void HTracer::TraceCompilation(CompilationInfo* info) { |
| Tag tag(this, "compilation"); |
| - Handle<String> name = function->debug_name(); |
| - PrintStringProperty("name", *name->ToCString()); |
| - PrintStringProperty("method", *name->ToCString()); |
| + if (info->IsOptimizing()) { |
| + Handle<String> name = info->function()->debug_name(); |
| + PrintStringProperty("name", *name->ToCString()); |
| + PrintStringProperty("method", *name->ToCString()); |
| + } else { |
| + PrintStringProperty("name", "stub"); |
|
Jakob Kummerow
2012/11/19 12:36:00
do we have more information here maybe? stub type?
danno
2012/11/26 17:16:18
unfortunately, no.
On 2012/11/19 12:36:00, Jakob
|
| + PrintStringProperty("method", "stub"); |
| + } |
| PrintLongProperty("date", static_cast<int64_t>(OS::TimeCurrentMillis())); |
| } |