OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 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 2803 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2814 // A constant map is fine. | 2814 // A constant map is fine. |
2815 Handle<Map> map(builder()->isolate()->get_initial_js_array_map(kind_), | 2815 Handle<Map> map(builder()->isolate()->get_initial_js_array_map(kind_), |
2816 builder()->isolate()); | 2816 builder()->isolate()); |
2817 return builder()->Add<HConstant>(map); | 2817 return builder()->Add<HConstant>(map); |
2818 } | 2818 } |
2819 | 2819 |
2820 if (constructor_function_ != NULL && kind_ == GetInitialFastElementsKind()) { | 2820 if (constructor_function_ != NULL && kind_ == GetInitialFastElementsKind()) { |
2821 // No need for a context lookup if the kind_ matches the initial | 2821 // No need for a context lookup if the kind_ matches the initial |
2822 // map, because we can just load the map in that case. | 2822 // map, because we can just load the map in that case. |
2823 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); | 2823 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); |
2824 return builder()->AddLoadNamedField(constructor_function_, access); | 2824 return builder()->Add<HLoadNamedField>( |
| 2825 constructor_function_, static_cast<HValue*>(NULL), access); |
2825 } | 2826 } |
2826 | 2827 |
2827 // TODO(mvstanton): we should always have a constructor function if we | 2828 // TODO(mvstanton): we should always have a constructor function if we |
2828 // are creating a stub. | 2829 // are creating a stub. |
2829 HInstruction* native_context = constructor_function_ != NULL | 2830 HInstruction* native_context = constructor_function_ != NULL |
2830 ? builder()->BuildGetNativeContext(constructor_function_) | 2831 ? builder()->BuildGetNativeContext(constructor_function_) |
2831 : builder()->BuildGetNativeContext(); | 2832 : builder()->BuildGetNativeContext(); |
2832 | 2833 |
2833 HInstruction* index = builder()->Add<HConstant>( | 2834 HInstruction* index = builder()->Add<HConstant>( |
2834 static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX)); | 2835 static_cast<int32_t>(Context::JS_ARRAY_MAPS_INDEX)); |
2835 | 2836 |
2836 HInstruction* map_array = builder()->Add<HLoadKeyed>( | 2837 HInstruction* map_array = builder()->Add<HLoadKeyed>( |
2837 native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS); | 2838 native_context, index, static_cast<HValue*>(NULL), FAST_ELEMENTS); |
2838 | 2839 |
2839 HInstruction* kind_index = builder()->Add<HConstant>(kind_); | 2840 HInstruction* kind_index = builder()->Add<HConstant>(kind_); |
2840 | 2841 |
2841 return builder()->Add<HLoadKeyed>( | 2842 return builder()->Add<HLoadKeyed>( |
2842 map_array, kind_index, static_cast<HValue*>(NULL), FAST_ELEMENTS); | 2843 map_array, kind_index, static_cast<HValue*>(NULL), FAST_ELEMENTS); |
2843 } | 2844 } |
2844 | 2845 |
2845 | 2846 |
2846 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { | 2847 HValue* HGraphBuilder::JSArrayBuilder::EmitInternalMapCode() { |
2847 // Find the map near the constructor function | 2848 // Find the map near the constructor function |
2848 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); | 2849 HObjectAccess access = HObjectAccess::ForPrototypeOrInitialMap(); |
2849 return builder()->AddLoadNamedField(constructor_function_, access); | 2850 return builder()->Add<HLoadNamedField>( |
| 2851 constructor_function_, static_cast<HValue*>(NULL), access); |
2850 } | 2852 } |
2851 | 2853 |
2852 | 2854 |
2853 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( | 2855 HValue* HGraphBuilder::JSArrayBuilder::EstablishAllocationSize( |
2854 HValue* length_node) { | 2856 HValue* length_node) { |
2855 ASSERT(length_node != NULL); | 2857 ASSERT(length_node != NULL); |
2856 | 2858 |
2857 int base_size = JSArray::kSize; | 2859 int base_size = JSArray::kSize; |
2858 if (mode_ == TRACK_ALLOCATION_SITE) { | 2860 if (mode_ == TRACK_ALLOCATION_SITE) { |
2859 base_size += AllocationMemento::kSize; | 2861 base_size += AllocationMemento::kSize; |
(...skipping 2022 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4882 | 4884 |
4883 return kUseCell; | 4885 return kUseCell; |
4884 } | 4886 } |
4885 | 4887 |
4886 | 4888 |
4887 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { | 4889 HValue* HOptimizedGraphBuilder::BuildContextChainWalk(Variable* var) { |
4888 ASSERT(var->IsContextSlot()); | 4890 ASSERT(var->IsContextSlot()); |
4889 HValue* context = environment()->context(); | 4891 HValue* context = environment()->context(); |
4890 int length = current_info()->scope()->ContextChainLength(var->scope()); | 4892 int length = current_info()->scope()->ContextChainLength(var->scope()); |
4891 while (length-- > 0) { | 4893 while (length-- > 0) { |
4892 context = AddLoadNamedField( | 4894 context = Add<HLoadNamedField>( |
4893 context, HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); | 4895 context, static_cast<HValue*>(NULL), |
| 4896 HObjectAccess::ForContextSlot(Context::PREVIOUS_INDEX)); |
4894 } | 4897 } |
4895 return context; | 4898 return context; |
4896 } | 4899 } |
4897 | 4900 |
4898 | 4901 |
4899 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { | 4902 void HOptimizedGraphBuilder::VisitVariableProxy(VariableProxy* expr) { |
4900 if (expr->is_this()) { | 4903 if (expr->is_this()) { |
4901 current_info()->set_this_has_uses(true); | 4904 current_info()->set_this_has_uses(true); |
4902 } | 4905 } |
4903 | 4906 |
(...skipping 433 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5337 } | 5340 } |
5338 | 5341 |
5339 | 5342 |
5340 HCheckMaps* HOptimizedGraphBuilder::AddCheckMap(HValue* object, | 5343 HCheckMaps* HOptimizedGraphBuilder::AddCheckMap(HValue* object, |
5341 Handle<Map> map) { | 5344 Handle<Map> map) { |
5342 BuildCheckHeapObject(object); | 5345 BuildCheckHeapObject(object); |
5343 return Add<HCheckMaps>(object, map, top_info()); | 5346 return Add<HCheckMaps>(object, map, top_info()); |
5344 } | 5347 } |
5345 | 5348 |
5346 | 5349 |
| 5350 HInstruction* HOptimizedGraphBuilder::BuildLoadNamedField( |
| 5351 PropertyAccessInfo* info, |
| 5352 HValue* checked_object) { |
| 5353 HObjectAccess access = info->access(); |
| 5354 if (access.representation().IsDouble()) { |
| 5355 // Load the heap number. |
| 5356 checked_object = Add<HLoadNamedField>( |
| 5357 checked_object, static_cast<HValue*>(NULL), |
| 5358 access.WithRepresentation(Representation::Tagged())); |
| 5359 checked_object->set_type(HType::HeapNumber()); |
| 5360 // Load the double value from it. |
| 5361 access = HObjectAccess::ForHeapNumberValue(); |
| 5362 } |
| 5363 return New<HLoadNamedField>( |
| 5364 checked_object, static_cast<HValue*>(NULL), access); |
| 5365 } |
| 5366 |
| 5367 |
5347 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( | 5368 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( |
5348 PropertyAccessInfo* info, | 5369 PropertyAccessInfo* info, |
5349 HValue* checked_object, | 5370 HValue* checked_object, |
5350 HValue* value) { | 5371 HValue* value) { |
5351 bool transition_to_field = info->lookup()->IsTransition(); | 5372 bool transition_to_field = info->lookup()->IsTransition(); |
5352 // TODO(verwaest): Move this logic into PropertyAccessInfo. | 5373 // TODO(verwaest): Move this logic into PropertyAccessInfo. |
5353 HObjectAccess field_access = HObjectAccess::ForField( | 5374 HObjectAccess field_access = HObjectAccess::ForField( |
5354 info->map(), info->lookup(), info->name()); | 5375 info->map(), info->lookup(), info->name()); |
5355 | 5376 |
5356 HStoreNamedField *instr; | 5377 HStoreNamedField *instr; |
5357 if (FLAG_track_double_fields && field_access.representation().IsDouble()) { | 5378 if (field_access.representation().IsDouble()) { |
5358 HObjectAccess heap_number_access = | 5379 HObjectAccess heap_number_access = |
5359 field_access.WithRepresentation(Representation::Tagged()); | 5380 field_access.WithRepresentation(Representation::Tagged()); |
5360 if (transition_to_field) { | 5381 if (transition_to_field) { |
5361 // The store requires a mutable HeapNumber to be allocated. | 5382 // The store requires a mutable HeapNumber to be allocated. |
5362 NoObservableSideEffectsScope no_side_effects(this); | 5383 NoObservableSideEffectsScope no_side_effects(this); |
5363 HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize); | 5384 HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize); |
5364 | 5385 |
5365 PretenureFlag pretenure_flag = !FLAG_allocation_site_pretenuring ? | 5386 PretenureFlag pretenure_flag = !FLAG_allocation_site_pretenuring ? |
5366 isolate()->heap()->GetPretenureMode() : NOT_TENURED; | 5387 isolate()->heap()->GetPretenureMode() : NOT_TENURED; |
5367 | 5388 |
(...skipping 240 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5608 checked_holder = BuildCheckPrototypeMaps(prototype, info->holder()); | 5629 checked_holder = BuildCheckPrototypeMaps(prototype, info->holder()); |
5609 } | 5630 } |
5610 | 5631 |
5611 if (!info->lookup()->IsFound()) { | 5632 if (!info->lookup()->IsFound()) { |
5612 ASSERT(info->IsLoad()); | 5633 ASSERT(info->IsLoad()); |
5613 return graph()->GetConstantUndefined(); | 5634 return graph()->GetConstantUndefined(); |
5614 } | 5635 } |
5615 | 5636 |
5616 if (info->lookup()->IsField()) { | 5637 if (info->lookup()->IsField()) { |
5617 if (info->IsLoad()) { | 5638 if (info->IsLoad()) { |
5618 return BuildLoadNamedField(checked_holder, info->access()); | 5639 return BuildLoadNamedField(info, checked_holder); |
5619 } else { | 5640 } else { |
5620 return BuildStoreNamedField(info, checked_object, value); | 5641 return BuildStoreNamedField(info, checked_object, value); |
5621 } | 5642 } |
5622 } | 5643 } |
5623 | 5644 |
5624 if (info->lookup()->IsTransition()) { | 5645 if (info->lookup()->IsTransition()) { |
5625 ASSERT(!info->IsLoad()); | 5646 ASSERT(!info->IsLoad()); |
5626 return BuildStoreNamedField(info, checked_object, value); | 5647 return BuildStoreNamedField(info, checked_object, value); |
5627 } | 5648 } |
5628 | 5649 |
(...skipping 550 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6179 | 6200 |
6180 // If the throw definitely exits the function, we can finish with a dummy | 6201 // If the throw definitely exits the function, we can finish with a dummy |
6181 // control flow at this point. This is not the case if the throw is inside | 6202 // control flow at this point. This is not the case if the throw is inside |
6182 // an inlined function which may be replaced. | 6203 // an inlined function which may be replaced. |
6183 if (call_context() == NULL) { | 6204 if (call_context() == NULL) { |
6184 FinishExitCurrentBlock(New<HAbnormalExit>()); | 6205 FinishExitCurrentBlock(New<HAbnormalExit>()); |
6185 } | 6206 } |
6186 } | 6207 } |
6187 | 6208 |
6188 | 6209 |
6189 HLoadNamedField* HGraphBuilder::BuildLoadNamedField(HValue* object, | |
6190 HObjectAccess access) { | |
6191 if (FLAG_track_double_fields && access.representation().IsDouble()) { | |
6192 // load the heap number | |
6193 HLoadNamedField* heap_number = Add<HLoadNamedField>( | |
6194 object, static_cast<HValue*>(NULL), | |
6195 access.WithRepresentation(Representation::Tagged())); | |
6196 heap_number->set_type(HType::HeapNumber()); | |
6197 // load the double value from it | |
6198 return New<HLoadNamedField>( | |
6199 heap_number, static_cast<HValue*>(NULL), | |
6200 HObjectAccess::ForHeapNumberValue()); | |
6201 } | |
6202 return New<HLoadNamedField>(object, static_cast<HValue*>(NULL), access); | |
6203 } | |
6204 | |
6205 | |
6206 HInstruction* HGraphBuilder::AddLoadNamedField(HValue* object, | |
6207 HObjectAccess access) { | |
6208 return AddInstruction(BuildLoadNamedField(object, access)); | |
6209 } | |
6210 | |
6211 | |
6212 HInstruction* HGraphBuilder::AddLoadStringInstanceType(HValue* string) { | 6210 HInstruction* HGraphBuilder::AddLoadStringInstanceType(HValue* string) { |
6213 if (string->IsConstant()) { | 6211 if (string->IsConstant()) { |
6214 HConstant* c_string = HConstant::cast(string); | 6212 HConstant* c_string = HConstant::cast(string); |
6215 if (c_string->HasStringValue()) { | 6213 if (c_string->HasStringValue()) { |
6216 return Add<HConstant>(c_string->StringValue()->map()->instance_type()); | 6214 return Add<HConstant>(c_string->StringValue()->map()->instance_type()); |
6217 } | 6215 } |
6218 } | 6216 } |
6219 return AddLoadNamedField( | 6217 return Add<HLoadNamedField>( |
6220 AddLoadNamedField(string, HObjectAccess::ForMap()), | 6218 Add<HLoadNamedField>(string, static_cast<HValue*>(NULL), |
6221 HObjectAccess::ForMapInstanceType()); | 6219 HObjectAccess::ForMap()), |
| 6220 static_cast<HValue*>(NULL), HObjectAccess::ForMapInstanceType()); |
6222 } | 6221 } |
6223 | 6222 |
6224 | 6223 |
6225 HInstruction* HGraphBuilder::AddLoadStringLength(HValue* string) { | 6224 HInstruction* HGraphBuilder::AddLoadStringLength(HValue* string) { |
6226 if (string->IsConstant()) { | 6225 if (string->IsConstant()) { |
6227 HConstant* c_string = HConstant::cast(string); | 6226 HConstant* c_string = HConstant::cast(string); |
6228 if (c_string->HasStringValue()) { | 6227 if (c_string->HasStringValue()) { |
6229 return Add<HConstant>(c_string->StringValue()->length()); | 6228 return Add<HConstant>(c_string->StringValue()->length()); |
6230 } | 6229 } |
6231 } | 6230 } |
6232 return AddLoadNamedField(string, HObjectAccess::ForStringLength()); | 6231 return Add<HLoadNamedField>(string, static_cast<HValue*>(NULL), |
| 6232 HObjectAccess::ForStringLength()); |
6233 } | 6233 } |
6234 | 6234 |
6235 | 6235 |
6236 HInstruction* HOptimizedGraphBuilder::BuildNamedGeneric( | 6236 HInstruction* HOptimizedGraphBuilder::BuildNamedGeneric( |
6237 PropertyAccessType access_type, | 6237 PropertyAccessType access_type, |
6238 HValue* object, | 6238 HValue* object, |
6239 Handle<String> name, | 6239 Handle<String> name, |
6240 HValue* value, | 6240 HValue* value, |
6241 bool is_uninitialized) { | 6241 bool is_uninitialized) { |
6242 if (is_uninitialized) { | 6242 if (is_uninitialized) { |
(...skipping 5048 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11291 if (ShouldProduceTraceOutput()) { | 11291 if (ShouldProduceTraceOutput()) { |
11292 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 11292 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
11293 } | 11293 } |
11294 | 11294 |
11295 #ifdef DEBUG | 11295 #ifdef DEBUG |
11296 graph_->Verify(false); // No full verify. | 11296 graph_->Verify(false); // No full verify. |
11297 #endif | 11297 #endif |
11298 } | 11298 } |
11299 | 11299 |
11300 } } // namespace v8::internal | 11300 } } // namespace v8::internal |
OLD | NEW |