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())); |
} |