OLD | NEW |
---|---|
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 11 matching lines...) Expand all Loading... | |
22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | 22 // LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, |
23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | 23 // DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY |
24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | 24 // THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | 25 // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE |
26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 26 // OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
27 | 27 |
28 #include "v8.h" | 28 #include "v8.h" |
29 #include "hydrogen.h" | 29 #include "hydrogen.h" |
30 | 30 |
31 #include "codegen.h" | 31 #include "codegen.h" |
32 #include "elements-hydrogen.h" | |
Jakob Kummerow
2012/11/19 12:36:00
remove
danno
2012/11/26 17:16:18
Done.
| |
32 #include "full-codegen.h" | 33 #include "full-codegen.h" |
33 #include "hashmap.h" | 34 #include "hashmap.h" |
34 #include "lithium-allocator.h" | 35 #include "lithium-allocator.h" |
35 #include "parser.h" | 36 #include "parser.h" |
36 #include "scopeinfo.h" | 37 #include "scopeinfo.h" |
37 #include "scopes.h" | 38 #include "scopes.h" |
38 #include "stub-cache.h" | 39 #include "stub-cache.h" |
39 | 40 |
40 #if V8_TARGET_ARCH_IA32 | 41 #if V8_TARGET_ARCH_IA32 |
41 #include "ia32/lithium-codegen-ia32.h" | 42 #include "ia32/lithium-codegen-ia32.h" |
(...skipping 88 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
130 } | 131 } |
131 | 132 |
132 return instr; | 133 return instr; |
133 } | 134 } |
134 | 135 |
135 | 136 |
136 HSimulate* HBasicBlock::CreateSimulate(BailoutId ast_id) { | 137 HSimulate* HBasicBlock::CreateSimulate(BailoutId ast_id) { |
137 ASSERT(HasEnvironment()); | 138 ASSERT(HasEnvironment()); |
138 HEnvironment* environment = last_environment(); | 139 HEnvironment* environment = last_environment(); |
139 ASSERT(ast_id.IsNone() || | 140 ASSERT(ast_id.IsNone() || |
141 ast_id == BailoutId::StubEntry() || | |
140 environment->closure()->shared()->VerifyBailoutId(ast_id)); | 142 environment->closure()->shared()->VerifyBailoutId(ast_id)); |
141 | 143 |
142 int push_count = environment->push_count(); | 144 int push_count = environment->push_count(); |
143 int pop_count = environment->pop_count(); | 145 int pop_count = environment->pop_count(); |
144 | 146 |
145 HSimulate* instr = new(zone()) HSimulate(ast_id, pop_count, zone()); | 147 HSimulate* instr = new(zone()) HSimulate(ast_id, pop_count, zone()); |
146 for (int i = push_count - 1; i >= 0; --i) { | 148 for (int i = push_count - 1; i >= 0; --i) { |
147 instr->AddPushedValue(environment->ExpressionStackAt(i)); | 149 instr->AddPushedValue(environment->ExpressionStackAt(i)); |
148 } | 150 } |
149 for (int i = 0; i < environment->assigned_variables()->length(); ++i) { | 151 for (int i = 0; i < environment->assigned_variables()->length(); ++i) { |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
268 if (IsLoopHeader()) { | 270 if (IsLoopHeader()) { |
269 ASSERT(phis()->length() == incoming_env->length()); | 271 ASSERT(phis()->length() == incoming_env->length()); |
270 for (int i = 0; i < phis_.length(); ++i) { | 272 for (int i = 0; i < phis_.length(); ++i) { |
271 phis_[i]->AddInput(incoming_env->values()->at(i)); | 273 phis_[i]->AddInput(incoming_env->values()->at(i)); |
272 } | 274 } |
273 } else { | 275 } else { |
274 last_environment()->AddIncomingEdge(this, pred->last_environment()); | 276 last_environment()->AddIncomingEdge(this, pred->last_environment()); |
275 } | 277 } |
276 } else if (!HasEnvironment() && !IsFinished()) { | 278 } else if (!HasEnvironment() && !IsFinished()) { |
277 ASSERT(!IsLoopHeader()); | 279 ASSERT(!IsLoopHeader()); |
278 SetInitialEnvironment(pred->last_environment()->Copy()); | 280 HEnvironment* last = pred->last_environment(); |
Jakob Kummerow
2012/11/19 12:36:00
remove this change?
danno
2012/11/26 17:16:18
Done.
| |
281 SetInitialEnvironment(last->Copy()); | |
279 } | 282 } |
280 | 283 |
281 predecessors_.Add(pred, zone()); | 284 predecessors_.Add(pred, zone()); |
282 } | 285 } |
283 | 286 |
284 | 287 |
285 void HBasicBlock::AddDominatedBlock(HBasicBlock* block) { | 288 void HBasicBlock::AddDominatedBlock(HBasicBlock* block) { |
286 ASSERT(!dominated_blocks_.Contains(block)); | 289 ASSERT(!dominated_blocks_.Contains(block)); |
287 // Keep the list of dominated blocks sorted such that if there is two | 290 // Keep the list of dominated blocks sorted such that if there is two |
288 // succeeding block in this list, the predecessor is before the successor. | 291 // succeeding block in this list, the predecessor is before the successor. |
(...skipping 402 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
691 entry_block_(NULL), | 694 entry_block_(NULL), |
692 blocks_(8, info->zone()), | 695 blocks_(8, info->zone()), |
693 values_(16, info->zone()), | 696 values_(16, info->zone()), |
694 phi_list_(NULL), | 697 phi_list_(NULL), |
695 uint32_instructions_(NULL), | 698 uint32_instructions_(NULL), |
696 info_(info), | 699 info_(info), |
697 zone_(info->zone()), | 700 zone_(info->zone()), |
698 is_recursive_(false), | 701 is_recursive_(false), |
699 use_optimistic_licm_(false), | 702 use_optimistic_licm_(false), |
700 type_change_checksum_(0) { | 703 type_change_checksum_(0) { |
701 start_environment_ = | 704 if (info->IsStub()) { |
702 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); | 705 start_environment_ = |
706 new(zone_) HEnvironment(zone_); | |
707 } else { | |
708 start_environment_ = | |
709 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); | |
710 } | |
703 start_environment_->set_ast_id(BailoutId::FunctionEntry()); | 711 start_environment_->set_ast_id(BailoutId::FunctionEntry()); |
704 entry_block_ = CreateBasicBlock(); | 712 entry_block_ = CreateBasicBlock(); |
705 entry_block_->SetInitialEnvironment(start_environment_); | 713 entry_block_->SetInitialEnvironment(start_environment_); |
706 } | 714 } |
707 | 715 |
708 | 716 |
709 HBasicBlock* HGraph::CreateBasicBlock() { | 717 HBasicBlock* HGraph::CreateBasicBlock() { |
710 HBasicBlock* result = new(zone()) HBasicBlock(this); | 718 HBasicBlock* result = new(zone()) HBasicBlock(this); |
711 blocks_.Add(result, zone()); | 719 blocks_.Add(result, zone()); |
712 return result; | 720 return result; |
713 } | 721 } |
714 | 722 |
715 | 723 |
716 void HGraph::Canonicalize() { | 724 void HGraph::Canonicalize() { |
717 if (!FLAG_use_canonicalizing) return; | 725 if (!FLAG_use_canonicalizing) return; |
718 HPhase phase("H_Canonicalize", this); | 726 HPhase phase("H_Canonicalize", this); |
719 for (int i = 0; i < blocks()->length(); ++i) { | 727 for (int i = 0; i < blocks()->length(); ++i) { |
720 HInstruction* instr = blocks()->at(i)->first(); | 728 HInstruction* instr = blocks()->at(i)->first(); |
721 while (instr != NULL) { | 729 while (instr != NULL) { |
722 HValue* value = instr->Canonicalize(); | 730 HValue* value = instr->Canonicalize(); |
723 if (value != instr) instr->DeleteAndReplaceWith(value); | 731 if (value != instr) instr->DeleteAndReplaceWith(value); |
724 instr = instr->next(); | 732 instr = instr->next(); |
725 } | 733 } |
726 } | 734 } |
727 } | 735 } |
728 | |
729 // Block ordering was implemented with two mutually recursive methods, | 736 // Block ordering was implemented with two mutually recursive methods, |
730 // HGraph::Postorder and HGraph::PostorderLoopBlocks. | 737 // HGraph::Postorder and HGraph::PostorderLoopBlocks. |
731 // The recursion could lead to stack overflow so the algorithm has been | 738 // The recursion could lead to stack overflow so the algorithm has been |
732 // implemented iteratively. | 739 // implemented iteratively. |
733 // At a high level the algorithm looks like this: | 740 // At a high level the algorithm looks like this: |
734 // | 741 // |
735 // Postorder(block, loop_header) : { | 742 // Postorder(block, loop_header) : { |
736 // if (block has already been visited or is of another loop) return; | 743 // if (block has already been visited or is of another loop) return; |
737 // mark block as visited; | 744 // mark block as visited; |
738 // if (block is a loop header) { | 745 // if (block is a loop header) { |
(...skipping 5285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6024 } | 6031 } |
6025 | 6032 |
6026 | 6033 |
6027 HInstruction* HGraphBuilder::BuildLoadKeyedGeneric(HValue* object, | 6034 HInstruction* HGraphBuilder::BuildLoadKeyedGeneric(HValue* object, |
6028 HValue* key) { | 6035 HValue* key) { |
6029 HValue* context = environment()->LookupContext(); | 6036 HValue* context = environment()->LookupContext(); |
6030 return new(zone()) HLoadKeyedGeneric(context, object, key); | 6037 return new(zone()) HLoadKeyedGeneric(context, object, key); |
6031 } | 6038 } |
6032 | 6039 |
6033 | 6040 |
6041 static HInstruction* AddBlockInstruction(HBasicBlock* current_block, | |
6042 HInstruction* instr) { | |
6043 ASSERT(current_block != NULL); | |
6044 current_block->AddInstruction(instr); | |
6045 return instr; | |
6046 } | |
6047 | |
6048 | |
6034 HInstruction* HGraphBuilder::BuildExternalArrayElementAccess( | 6049 HInstruction* HGraphBuilder::BuildExternalArrayElementAccess( |
6050 HGraph* graph, | |
6051 HBasicBlock* current_block, | |
6035 HValue* external_elements, | 6052 HValue* external_elements, |
6036 HValue* checked_key, | 6053 HValue* checked_key, |
6037 HValue* val, | 6054 HValue* val, |
6038 HValue* dependency, | 6055 HValue* dependency, |
6039 ElementsKind elements_kind, | 6056 ElementsKind elements_kind, |
6040 bool is_store) { | 6057 bool is_store, |
6058 Zone* zone) { | |
6041 if (is_store) { | 6059 if (is_store) { |
6042 ASSERT(val != NULL); | 6060 ASSERT(val != NULL); |
6043 switch (elements_kind) { | 6061 switch (elements_kind) { |
6044 case EXTERNAL_PIXEL_ELEMENTS: { | 6062 case EXTERNAL_PIXEL_ELEMENTS: { |
6045 val = AddInstruction(new(zone()) HClampToUint8(val)); | 6063 val = AddBlockInstruction(current_block, new(zone) HClampToUint8(val)); |
6046 break; | 6064 break; |
6047 } | 6065 } |
6048 case EXTERNAL_BYTE_ELEMENTS: | 6066 case EXTERNAL_BYTE_ELEMENTS: |
6049 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 6067 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
6050 case EXTERNAL_SHORT_ELEMENTS: | 6068 case EXTERNAL_SHORT_ELEMENTS: |
6051 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 6069 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
6052 case EXTERNAL_INT_ELEMENTS: | 6070 case EXTERNAL_INT_ELEMENTS: |
6053 case EXTERNAL_UNSIGNED_INT_ELEMENTS: { | 6071 case EXTERNAL_UNSIGNED_INT_ELEMENTS: { |
6054 if (!val->representation().IsInteger32()) { | 6072 if (!val->representation().IsInteger32()) { |
6055 val = AddInstruction(new(zone()) HChange( | 6073 val = AddBlockInstruction(current_block, new(zone) HChange( |
6056 val, | 6074 val, |
6057 Representation::Integer32(), | 6075 Representation::Integer32(), |
6058 true, // Truncate to int32. | 6076 true, // Truncate to int32. |
6059 false)); // Don't deoptimize undefined (irrelevant here). | 6077 false)); // Don't deoptimize undefined (irrelevant here). |
6060 } | 6078 } |
6061 break; | 6079 break; |
6062 } | 6080 } |
6063 case EXTERNAL_FLOAT_ELEMENTS: | 6081 case EXTERNAL_FLOAT_ELEMENTS: |
6064 case EXTERNAL_DOUBLE_ELEMENTS: | 6082 case EXTERNAL_DOUBLE_ELEMENTS: |
6065 break; | 6083 break; |
6066 case FAST_SMI_ELEMENTS: | 6084 case FAST_SMI_ELEMENTS: |
6067 case FAST_ELEMENTS: | 6085 case FAST_ELEMENTS: |
6068 case FAST_DOUBLE_ELEMENTS: | 6086 case FAST_DOUBLE_ELEMENTS: |
6069 case FAST_HOLEY_SMI_ELEMENTS: | 6087 case FAST_HOLEY_SMI_ELEMENTS: |
6070 case FAST_HOLEY_ELEMENTS: | 6088 case FAST_HOLEY_ELEMENTS: |
6071 case FAST_HOLEY_DOUBLE_ELEMENTS: | 6089 case FAST_HOLEY_DOUBLE_ELEMENTS: |
6072 case DICTIONARY_ELEMENTS: | 6090 case DICTIONARY_ELEMENTS: |
6073 case NON_STRICT_ARGUMENTS_ELEMENTS: | 6091 case NON_STRICT_ARGUMENTS_ELEMENTS: |
6074 UNREACHABLE(); | 6092 UNREACHABLE(); |
6075 break; | 6093 break; |
6076 } | 6094 } |
6077 return new(zone()) HStoreKeyed(external_elements, | 6095 return new(zone) HStoreKeyed(external_elements, |
6078 checked_key, | 6096 checked_key, |
Jakob Kummerow
2012/11/19 12:36:00
nit: indentation
danno
2012/11/26 17:16:18
Done.
| |
6079 val, | 6097 val, |
6080 elements_kind); | 6098 elements_kind); |
6081 } else { | 6099 } else { |
6082 ASSERT(val == NULL); | 6100 ASSERT(val == NULL); |
6083 HLoadKeyed* load = | 6101 HLoadKeyed* load = |
6084 new(zone()) HLoadKeyed( | 6102 new(zone) HLoadKeyed( |
6085 external_elements, checked_key, dependency, elements_kind); | 6103 external_elements, checked_key, dependency, elements_kind); |
6086 if (FLAG_opt_safe_uint32_operations && | 6104 if (FLAG_opt_safe_uint32_operations && |
6087 elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) { | 6105 elements_kind == EXTERNAL_UNSIGNED_INT_ELEMENTS) { |
6088 graph()->RecordUint32Instruction(load); | 6106 graph->RecordUint32Instruction(load); |
6089 } | 6107 } |
6090 return load; | 6108 return load; |
6091 } | 6109 } |
6092 } | 6110 } |
6093 | 6111 |
6094 | 6112 |
6095 HInstruction* HGraphBuilder::BuildFastElementAccess(HValue* elements, | 6113 HInstruction* HGraphBuilder::BuildFastElementAccess(HGraph* graph, |
6114 HBasicBlock* current_block, | |
6115 HValue* elements, | |
6096 HValue* checked_key, | 6116 HValue* checked_key, |
6097 HValue* val, | 6117 HValue* val, |
6098 HValue* load_dependency, | 6118 HValue* load_dependency, |
6099 ElementsKind elements_kind, | 6119 ElementsKind elements_kind, |
6100 bool is_store) { | 6120 bool is_store, |
6121 Zone* zone) { | |
6101 if (is_store) { | 6122 if (is_store) { |
6102 ASSERT(val != NULL); | 6123 ASSERT(val != NULL); |
6103 switch (elements_kind) { | 6124 switch (elements_kind) { |
6104 case FAST_SMI_ELEMENTS: | 6125 case FAST_SMI_ELEMENTS: |
6105 case FAST_HOLEY_SMI_ELEMENTS: | 6126 case FAST_HOLEY_SMI_ELEMENTS: |
6106 // Smi-only arrays need a smi check. | 6127 // Smi-only arrays need a smi check. |
6107 AddInstruction(new(zone()) HCheckSmi(val)); | 6128 AddBlockInstruction(current_block, new(zone) HCheckSmi(val)); |
6108 // Fall through. | 6129 // Fall through. |
6109 case FAST_ELEMENTS: | 6130 case FAST_ELEMENTS: |
6110 case FAST_HOLEY_ELEMENTS: | 6131 case FAST_HOLEY_ELEMENTS: |
6111 case FAST_DOUBLE_ELEMENTS: | 6132 case FAST_DOUBLE_ELEMENTS: |
6112 case FAST_HOLEY_DOUBLE_ELEMENTS: | 6133 case FAST_HOLEY_DOUBLE_ELEMENTS: |
6113 return new(zone()) HStoreKeyed( | 6134 return new(zone) HStoreKeyed(elements, checked_key, val, elements_kind); |
6114 elements, checked_key, val, elements_kind); | |
6115 default: | 6135 default: |
6116 UNREACHABLE(); | 6136 UNREACHABLE(); |
6117 return NULL; | 6137 return NULL; |
6118 } | 6138 } |
6119 } | 6139 } |
6120 // It's an element load (!is_store). | 6140 // It's an element load (!is_store). |
6121 return new(zone()) HLoadKeyed(elements, | 6141 return new(zone) HLoadKeyed(elements, |
6122 checked_key, | 6142 checked_key, |
6123 load_dependency, | 6143 load_dependency, |
6124 elements_kind); | 6144 elements_kind); |
6125 } | 6145 } |
6126 | 6146 |
6127 | 6147 |
6128 HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object, | 6148 HInstruction* HGraphBuilder::BuildMonomorphicElementAccess(HValue* object, |
6129 HValue* key, | 6149 HValue* key, |
6130 HValue* val, | 6150 HValue* val, |
6131 HValue* dependency, | 6151 HValue* dependency, |
6132 Handle<Map> map, | 6152 Handle<Map> map, |
6133 bool is_store) { | 6153 bool is_store) { |
6134 HCheckMaps* mapcheck = new(zone()) HCheckMaps(object, map, | 6154 HCheckMaps* mapcheck = new(zone()) HCheckMaps(object, map, |
6135 zone(), dependency); | 6155 zone(), dependency); |
6136 AddInstruction(mapcheck); | 6156 AddInstruction(mapcheck); |
6137 if (dependency) { | 6157 if (dependency) { |
6138 mapcheck->ClearGVNFlag(kDependsOnElementsKind); | 6158 mapcheck->ClearGVNFlag(kDependsOnElementsKind); |
6139 } | 6159 } |
6140 return BuildUncheckedMonomorphicElementAccess(object, key, val, | 6160 return BuildUncheckedMonomorphicElementAccess( |
6141 mapcheck, map, is_store); | 6161 graph(), |
6162 current_block(), object, key, val, | |
6163 mapcheck, map->instance_type() == JS_ARRAY_TYPE, | |
6164 map->elements_kind(), is_store, zone()); | |
6142 } | 6165 } |
6143 | 6166 |
6144 | 6167 |
6145 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( | 6168 HInstruction* HGraphBuilder::BuildUncheckedMonomorphicElementAccess( |
6169 HGraph* graph, | |
6170 HBasicBlock* current_block, | |
6146 HValue* object, | 6171 HValue* object, |
6147 HValue* key, | 6172 HValue* key, |
6148 HValue* val, | 6173 HValue* val, |
6149 HCheckMaps* mapcheck, | 6174 HCheckMaps* mapcheck, |
6150 Handle<Map> map, | 6175 bool is_js_array, |
6151 bool is_store) { | 6176 ElementsKind elements_kind, |
6177 bool is_store, | |
6178 Zone* zone) { | |
6152 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency | 6179 // No GVNFlag is necessary for ElementsKind if there is an explicit dependency |
6153 // on a HElementsTransition instruction. The flag can also be removed if the | 6180 // on a HElementsTransition instruction. The flag can also be removed if the |
6154 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further | 6181 // map to check has FAST_HOLEY_ELEMENTS, since there can be no further |
6155 // ElementsKind transitions. Finally, the dependency can be removed for stores | 6182 // ElementsKind transitions. Finally, the dependency can be removed for stores |
6156 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the | 6183 // for FAST_ELEMENTS, since a transition to HOLEY elements won't change the |
6157 // generated store code. | 6184 // generated store code. |
6158 if ((map->elements_kind() == FAST_HOLEY_ELEMENTS) || | 6185 if ((elements_kind == FAST_HOLEY_ELEMENTS) || |
6159 (map->elements_kind() == FAST_ELEMENTS && is_store)) { | 6186 (elements_kind == FAST_ELEMENTS && is_store)) { |
6160 mapcheck->ClearGVNFlag(kDependsOnElementsKind); | 6187 if (mapcheck != NULL) { |
6188 mapcheck->ClearGVNFlag(kDependsOnElementsKind); | |
6189 } | |
6161 } | 6190 } |
6162 bool fast_smi_only_elements = map->has_fast_smi_elements(); | 6191 bool fast_smi_only_elements = IsFastSmiElementsKind(elements_kind); |
6163 bool fast_elements = map->has_fast_object_elements(); | 6192 bool fast_elements = IsFastObjectElementsKind(elements_kind); |
6164 HInstruction* elements = | 6193 HInstruction* elements = |
6165 AddInstruction(new(zone()) HLoadElements(object, mapcheck)); | 6194 AddBlockInstruction(current_block, |
6195 new(zone) HLoadElements(object, mapcheck)); | |
6166 if (is_store && (fast_elements || fast_smi_only_elements)) { | 6196 if (is_store && (fast_elements || fast_smi_only_elements)) { |
6167 HCheckMaps* check_cow_map = new(zone()) HCheckMaps( | 6197 HCheckMaps* check_cow_map = new(zone) HCheckMaps( |
6168 elements, isolate()->factory()->fixed_array_map(), zone()); | 6198 elements, Isolate::Current()->factory()->fixed_array_map(), zone); |
6169 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); | 6199 check_cow_map->ClearGVNFlag(kDependsOnElementsKind); |
6170 AddInstruction(check_cow_map); | 6200 AddBlockInstruction(current_block, check_cow_map); |
6171 } | 6201 } |
6172 HInstruction* length = NULL; | 6202 HInstruction* length = NULL; |
6173 HInstruction* checked_key = NULL; | 6203 HInstruction* checked_key = NULL; |
6174 if (map->has_external_array_elements()) { | 6204 if (IsExternalArrayElementsKind(elements_kind)) { |
6175 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); | 6205 length = AddBlockInstruction(current_block, |
6176 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length, | 6206 new(zone) HFixedArrayBaseLength(elements)); |
6177 ALLOW_SMI_KEY)); | 6207 checked_key = AddBlockInstruction(current_block, |
6208 new(zone) HBoundsCheck(key, length, | |
6209 ALLOW_SMI_KEY)); | |
6178 HLoadExternalArrayPointer* external_elements = | 6210 HLoadExternalArrayPointer* external_elements = |
6179 new(zone()) HLoadExternalArrayPointer(elements); | 6211 new(zone) HLoadExternalArrayPointer(elements); |
6180 AddInstruction(external_elements); | 6212 AddBlockInstruction(current_block, external_elements); |
6181 return BuildExternalArrayElementAccess( | 6213 return BuildExternalArrayElementAccess(graph, |
6182 external_elements, checked_key, val, mapcheck, | 6214 current_block, external_elements, checked_key, val, mapcheck, |
6183 map->elements_kind(), is_store); | 6215 elements_kind, is_store, zone); |
6184 } | 6216 } |
6185 ASSERT(fast_smi_only_elements || | 6217 ASSERT(fast_smi_only_elements || |
6186 fast_elements || | 6218 fast_elements || |
6187 map->has_fast_double_elements()); | 6219 IsFastDoubleElementsKind(elements_kind)); |
6188 if (map->instance_type() == JS_ARRAY_TYPE) { | 6220 if (is_js_array) { |
6189 length = AddInstruction(new(zone()) HJSArrayLength(object, mapcheck, | 6221 length = AddBlockInstruction(current_block, |
6190 HType::Smi())); | 6222 new(zone) HJSArrayLength(object, mapcheck, |
6223 HType::Smi())); | |
6191 } else { | 6224 } else { |
6192 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); | 6225 length = AddBlockInstruction(current_block, |
6226 new(zone) HFixedArrayBaseLength(elements)); | |
6193 } | 6227 } |
6194 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length, | 6228 checked_key = AddBlockInstruction(current_block, |
6195 ALLOW_SMI_KEY)); | 6229 new(zone) HBoundsCheck(key, length, |
6196 return BuildFastElementAccess(elements, checked_key, val, mapcheck, | 6230 ALLOW_SMI_KEY)); |
6197 map->elements_kind(), is_store); | 6231 return BuildFastElementAccess(graph, current_block, |
6232 elements, checked_key, val, mapcheck, | |
6233 elements_kind, is_store, zone); | |
6198 } | 6234 } |
6199 | 6235 |
6200 | 6236 |
6201 HInstruction* HGraphBuilder::TryBuildConsolidatedElementLoad( | 6237 HInstruction* HGraphBuilder::TryBuildConsolidatedElementLoad( |
6202 HValue* object, | 6238 HValue* object, |
6203 HValue* key, | 6239 HValue* key, |
6204 HValue* val, | 6240 HValue* val, |
6205 SmallMapList* maps) { | 6241 SmallMapList* maps) { |
6206 // For polymorphic loads of similar elements kinds (i.e. all tagged or all | 6242 // For polymorphic loads of similar elements kinds (i.e. all tagged or all |
6207 // double), always use the "worst case" code without a transition. This is | 6243 // double), always use the "worst case" code without a transition. This is |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6239 most_general_consolidated_map->elements_kind(), | 6275 most_general_consolidated_map->elements_kind(), |
6240 map->elements_kind())) { | 6276 map->elements_kind())) { |
6241 most_general_consolidated_map = map; | 6277 most_general_consolidated_map = map; |
6242 } | 6278 } |
6243 } | 6279 } |
6244 if (!has_double_maps && !has_smi_or_object_maps) return NULL; | 6280 if (!has_double_maps && !has_smi_or_object_maps) return NULL; |
6245 | 6281 |
6246 HCheckMaps* check_maps = new(zone()) HCheckMaps(object, maps, zone()); | 6282 HCheckMaps* check_maps = new(zone()) HCheckMaps(object, maps, zone()); |
6247 AddInstruction(check_maps); | 6283 AddInstruction(check_maps); |
6248 HInstruction* instr = BuildUncheckedMonomorphicElementAccess( | 6284 HInstruction* instr = BuildUncheckedMonomorphicElementAccess( |
6249 object, key, val, check_maps, most_general_consolidated_map, false); | 6285 graph(), |
6286 current_block(), object, key, val, check_maps, | |
6287 most_general_consolidated_map->instance_type() == JS_ARRAY_TYPE, | |
6288 most_general_consolidated_map->elements_kind(), | |
6289 false, zone()); | |
6250 return instr; | 6290 return instr; |
6251 } | 6291 } |
6252 | 6292 |
6253 | 6293 |
6254 HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object, | 6294 HValue* HGraphBuilder::HandlePolymorphicElementAccess(HValue* object, |
6255 HValue* key, | 6295 HValue* key, |
6256 HValue* val, | 6296 HValue* val, |
6257 Expression* prop, | 6297 Expression* prop, |
6258 BailoutId ast_id, | 6298 BailoutId ast_id, |
6259 int position, | 6299 int position, |
(...skipping 149 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
6409 typecheck->SetSuccessorAt(1, if_fastobject); | 6449 typecheck->SetSuccessorAt(1, if_fastobject); |
6410 current_block()->Finish(typecheck); | 6450 current_block()->Finish(typecheck); |
6411 | 6451 |
6412 set_current_block(if_jsarray); | 6452 set_current_block(if_jsarray); |
6413 HInstruction* length; | 6453 HInstruction* length; |
6414 length = AddInstruction(new(zone()) HJSArrayLength(object, typecheck, | 6454 length = AddInstruction(new(zone()) HJSArrayLength(object, typecheck, |
6415 HType::Smi())); | 6455 HType::Smi())); |
6416 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length, | 6456 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length, |
6417 ALLOW_SMI_KEY)); | 6457 ALLOW_SMI_KEY)); |
6418 access = AddInstruction(BuildFastElementAccess( | 6458 access = AddInstruction(BuildFastElementAccess( |
6419 elements, checked_key, val, elements_kind_branch, | 6459 graph(), |
6420 elements_kind, is_store)); | 6460 current_block(), elements, checked_key, val, elements_kind_branch, |
6461 elements_kind, is_store, zone())); | |
6421 if (!is_store) { | 6462 if (!is_store) { |
6422 Push(access); | 6463 Push(access); |
6423 } | 6464 } |
6424 | 6465 |
6425 *has_side_effects |= access->HasObservableSideEffects(); | 6466 *has_side_effects |= access->HasObservableSideEffects(); |
6426 if (position != -1) { | 6467 if (position != -1) { |
6427 access->set_position(position); | 6468 access->set_position(position); |
6428 } | 6469 } |
6429 if_jsarray->Goto(join); | 6470 if_jsarray->Goto(join); |
6430 | 6471 |
6431 set_current_block(if_fastobject); | 6472 set_current_block(if_fastobject); |
6432 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); | 6473 length = AddInstruction(new(zone()) HFixedArrayBaseLength(elements)); |
6433 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length, | 6474 checked_key = AddInstruction(new(zone()) HBoundsCheck(key, length, |
6434 ALLOW_SMI_KEY)); | 6475 ALLOW_SMI_KEY)); |
6435 access = AddInstruction(BuildFastElementAccess( | 6476 access = AddInstruction(BuildFastElementAccess( |
6477 graph(), | |
6478 current_block(), | |
6436 elements, checked_key, val, elements_kind_branch, | 6479 elements, checked_key, val, elements_kind_branch, |
6437 elements_kind, is_store)); | 6480 elements_kind, is_store, zone())); |
6438 } else if (elements_kind == DICTIONARY_ELEMENTS) { | 6481 } else if (elements_kind == DICTIONARY_ELEMENTS) { |
6439 if (is_store) { | 6482 if (is_store) { |
6440 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); | 6483 access = AddInstruction(BuildStoreKeyedGeneric(object, key, val)); |
6441 } else { | 6484 } else { |
6442 access = AddInstruction(BuildLoadKeyedGeneric(object, key)); | 6485 access = AddInstruction(BuildLoadKeyedGeneric(object, key)); |
6443 } | 6486 } |
6444 } else { // External array elements. | 6487 } else { // External array elements. |
6445 access = AddInstruction(BuildExternalArrayElementAccess( | 6488 access = AddInstruction(BuildExternalArrayElementAccess( |
6446 external_elements, checked_key, val, elements_kind_branch, | 6489 graph(), |
6447 elements_kind, is_store)); | 6490 current_block(), external_elements, checked_key, val, |
6491 elements_kind_branch, | |
6492 elements_kind, is_store, zone())); | |
6448 } | 6493 } |
6449 *has_side_effects |= access->HasObservableSideEffects(); | 6494 *has_side_effects |= access->HasObservableSideEffects(); |
6450 if (position != RelocInfo::kNoPosition) access->set_position(position); | 6495 if (position != RelocInfo::kNoPosition) access->set_position(position); |
6451 if (!is_store) { | 6496 if (!is_store) { |
6452 Push(access); | 6497 Push(access); |
6453 } | 6498 } |
6454 current_block()->Goto(join); | 6499 current_block()->Goto(join); |
6455 set_current_block(if_false); | 6500 set_current_block(if_false); |
6456 } | 6501 } |
6457 } | 6502 } |
(...skipping 3025 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9483 outer_(outer), | 9528 outer_(outer), |
9484 entry_(NULL), | 9529 entry_(NULL), |
9485 pop_count_(0), | 9530 pop_count_(0), |
9486 push_count_(0), | 9531 push_count_(0), |
9487 ast_id_(BailoutId::None()), | 9532 ast_id_(BailoutId::None()), |
9488 zone_(zone) { | 9533 zone_(zone) { |
9489 Initialize(scope->num_parameters() + 1, scope->num_stack_slots(), 0); | 9534 Initialize(scope->num_parameters() + 1, scope->num_stack_slots(), 0); |
9490 } | 9535 } |
9491 | 9536 |
9492 | 9537 |
9538 HEnvironment::HEnvironment(Zone* zone) | |
9539 : values_(0, zone), | |
9540 assigned_variables_(0, zone), | |
9541 frame_type_(STUB), | |
9542 parameter_count_(0), | |
9543 specials_count_(0), | |
9544 local_count_(0), | |
9545 outer_(NULL), | |
9546 entry_(NULL), | |
9547 pop_count_(0), | |
9548 push_count_(0), | |
9549 ast_id_(BailoutId::None()), | |
9550 zone_(zone) { | |
9551 Initialize(0, 0, 0); | |
9552 } | |
9553 | |
9554 | |
9493 HEnvironment::HEnvironment(const HEnvironment* other, Zone* zone) | 9555 HEnvironment::HEnvironment(const HEnvironment* other, Zone* zone) |
9494 : values_(0, zone), | 9556 : values_(0, zone), |
9495 assigned_variables_(0, zone), | 9557 assigned_variables_(0, zone), |
9496 frame_type_(JS_FUNCTION), | 9558 frame_type_(JS_FUNCTION), |
9497 parameter_count_(0), | 9559 parameter_count_(0), |
9498 specials_count_(1), | 9560 specials_count_(1), |
9499 local_count_(0), | 9561 local_count_(0), |
9500 outer_(NULL), | 9562 outer_(NULL), |
9501 entry_(NULL), | 9563 entry_(NULL), |
9502 pop_count_(0), | 9564 pop_count_(0), |
(...skipping 247 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
9750 | 9812 |
9751 | 9813 |
9752 void HEnvironment::PrintToStd() { | 9814 void HEnvironment::PrintToStd() { |
9753 HeapStringAllocator string_allocator; | 9815 HeapStringAllocator string_allocator; |
9754 StringStream trace(&string_allocator); | 9816 StringStream trace(&string_allocator); |
9755 PrintTo(&trace); | 9817 PrintTo(&trace); |
9756 PrintF("%s", *trace.ToCString()); | 9818 PrintF("%s", *trace.ToCString()); |
9757 } | 9819 } |
9758 | 9820 |
9759 | 9821 |
9760 void HTracer::TraceCompilation(FunctionLiteral* function) { | 9822 void HTracer::TraceCompilation(CompilationInfo* info) { |
9761 Tag tag(this, "compilation"); | 9823 Tag tag(this, "compilation"); |
9762 Handle<String> name = function->debug_name(); | 9824 if (info->IsOptimizing()) { |
9763 PrintStringProperty("name", *name->ToCString()); | 9825 Handle<String> name = info->function()->debug_name(); |
9764 PrintStringProperty("method", *name->ToCString()); | 9826 PrintStringProperty("name", *name->ToCString()); |
9827 PrintStringProperty("method", *name->ToCString()); | |
9828 } else { | |
9829 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
| |
9830 PrintStringProperty("method", "stub"); | |
9831 } | |
9765 PrintLongProperty("date", static_cast<int64_t>(OS::TimeCurrentMillis())); | 9832 PrintLongProperty("date", static_cast<int64_t>(OS::TimeCurrentMillis())); |
9766 } | 9833 } |
9767 | 9834 |
9768 | 9835 |
9769 void HTracer::TraceLithium(const char* name, LChunk* chunk) { | 9836 void HTracer::TraceLithium(const char* name, LChunk* chunk) { |
9770 Trace(name, chunk->graph(), chunk); | 9837 Trace(name, chunk->graph(), chunk); |
9771 } | 9838 } |
9772 | 9839 |
9773 | 9840 |
9774 void HTracer::TraceHydrogen(const char* name, HGraph* graph) { | 9841 void HTracer::TraceHydrogen(const char* name, HGraph* graph) { |
(...skipping 295 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
10070 } | 10137 } |
10071 } | 10138 } |
10072 | 10139 |
10073 #ifdef DEBUG | 10140 #ifdef DEBUG |
10074 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 10141 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
10075 if (allocator_ != NULL) allocator_->Verify(); | 10142 if (allocator_ != NULL) allocator_->Verify(); |
10076 #endif | 10143 #endif |
10077 } | 10144 } |
10078 | 10145 |
10079 } } // namespace v8::internal | 10146 } } // namespace v8::internal |
OLD | NEW |