OLD | NEW |
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "hydrogen.h" | 5 #include "hydrogen.h" |
6 | 6 |
7 #include <algorithm> | 7 #include <algorithm> |
8 | 8 |
9 #include "v8.h" | 9 #include "v8.h" |
10 #include "allocation-site-scopes.h" | 10 #include "allocation-site-scopes.h" |
(...skipping 5428 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5439 } | 5439 } |
5440 } | 5440 } |
5441 } | 5441 } |
5442 | 5442 |
5443 HObjectAccess access = info->access(); | 5443 HObjectAccess access = info->access(); |
5444 if (access.representation().IsDouble()) { | 5444 if (access.representation().IsDouble()) { |
5445 // Load the heap number. | 5445 // Load the heap number. |
5446 checked_object = Add<HLoadNamedField>( | 5446 checked_object = Add<HLoadNamedField>( |
5447 checked_object, static_cast<HValue*>(NULL), | 5447 checked_object, static_cast<HValue*>(NULL), |
5448 access.WithRepresentation(Representation::Tagged())); | 5448 access.WithRepresentation(Representation::Tagged())); |
5449 checked_object->set_type(HType::HeapNumber()); | |
5450 // Load the double value from it. | 5449 // Load the double value from it. |
5451 access = HObjectAccess::ForHeapNumberValue(); | 5450 access = HObjectAccess::ForHeapNumberValue(); |
5452 } | 5451 } |
5453 | 5452 |
5454 SmallMapList* map_list = info->field_maps(); | 5453 SmallMapList* map_list = info->field_maps(); |
5455 if (map_list->length() == 0) { | 5454 if (map_list->length() == 0) { |
5456 return New<HLoadNamedField>(checked_object, checked_object, access); | 5455 return New<HLoadNamedField>(checked_object, checked_object, access); |
5457 } | 5456 } |
5458 | 5457 |
5459 UniqueSet<Map>* maps = new(zone()) UniqueSet<Map>(map_list->length(), zone()); | 5458 UniqueSet<Map>* maps = new(zone()) UniqueSet<Map>(map_list->length(), zone()); |
(...skipping 18 matching lines...) Expand all Loading... |
5478 HObjectAccess heap_number_access = | 5477 HObjectAccess heap_number_access = |
5479 field_access.WithRepresentation(Representation::Tagged()); | 5478 field_access.WithRepresentation(Representation::Tagged()); |
5480 if (transition_to_field) { | 5479 if (transition_to_field) { |
5481 // The store requires a mutable HeapNumber to be allocated. | 5480 // The store requires a mutable HeapNumber to be allocated. |
5482 NoObservableSideEffectsScope no_side_effects(this); | 5481 NoObservableSideEffectsScope no_side_effects(this); |
5483 HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize); | 5482 HInstruction* heap_number_size = Add<HConstant>(HeapNumber::kSize); |
5484 | 5483 |
5485 PretenureFlag pretenure_flag = !FLAG_allocation_site_pretenuring ? | 5484 PretenureFlag pretenure_flag = !FLAG_allocation_site_pretenuring ? |
5486 isolate()->heap()->GetPretenureMode() : NOT_TENURED; | 5485 isolate()->heap()->GetPretenureMode() : NOT_TENURED; |
5487 | 5486 |
| 5487 // Mark mutable heap numbers as Tagged rather than HeapNumber, since |
| 5488 // unlike immutable heap numbers, the identity of mutable heap numbers |
| 5489 // matters. |
5488 HInstruction* heap_number = Add<HAllocate>(heap_number_size, | 5490 HInstruction* heap_number = Add<HAllocate>(heap_number_size, |
5489 HType::HeapNumber(), | 5491 HType::Tagged(), |
5490 pretenure_flag, | 5492 pretenure_flag, |
5491 HEAP_NUMBER_TYPE); | 5493 HEAP_NUMBER_TYPE); |
5492 AddStoreMapConstant(heap_number, isolate()->factory()->heap_number_map()); | 5494 AddStoreMapConstant(heap_number, isolate()->factory()->heap_number_map()); |
5493 Add<HStoreNamedField>(heap_number, HObjectAccess::ForHeapNumberValue(), | 5495 Add<HStoreNamedField>(heap_number, HObjectAccess::ForHeapNumberValue(), |
5494 value); | 5496 value); |
5495 instr = New<HStoreNamedField>(checked_object->ActualValue(), | 5497 instr = New<HStoreNamedField>(checked_object->ActualValue(), |
5496 heap_number_access, | 5498 heap_number_access, |
5497 heap_number); | 5499 heap_number); |
5498 } else { | 5500 } else { |
5499 // Already holds a HeapNumber; load the box and write its value field. | 5501 // Already holds a HeapNumber; load the box and write its value field. |
5500 HInstruction* heap_number = Add<HLoadNamedField>( | 5502 HInstruction* heap_number = Add<HLoadNamedField>( |
5501 checked_object, static_cast<HValue*>(NULL), heap_number_access); | 5503 checked_object, static_cast<HValue*>(NULL), heap_number_access); |
5502 heap_number->set_type(HType::HeapNumber()); | |
5503 instr = New<HStoreNamedField>(heap_number, | 5504 instr = New<HStoreNamedField>(heap_number, |
5504 HObjectAccess::ForHeapNumberValue(), | 5505 HObjectAccess::ForHeapNumberValue(), |
5505 value, STORE_TO_INITIALIZED_ENTRY); | 5506 value, STORE_TO_INITIALIZED_ENTRY); |
5506 } | 5507 } |
5507 } else { | 5508 } else { |
5508 if (!info->field_maps()->is_empty()) { | 5509 if (!info->field_maps()->is_empty()) { |
5509 ASSERT(field_access.representation().IsHeapObject()); | 5510 ASSERT(field_access.representation().IsHeapObject()); |
5510 BuildCheckHeapObject(value); | 5511 BuildCheckHeapObject(value); |
5511 value = Add<HCheckMaps>(value, info->field_maps()); | 5512 value = Add<HCheckMaps>(value, info->field_maps()); |
5512 | 5513 |
(...skipping 6300 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11813 if (ShouldProduceTraceOutput()) { | 11814 if (ShouldProduceTraceOutput()) { |
11814 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 11815 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
11815 } | 11816 } |
11816 | 11817 |
11817 #ifdef DEBUG | 11818 #ifdef DEBUG |
11818 graph_->Verify(false); // No full verify. | 11819 graph_->Verify(false); // No full verify. |
11819 #endif | 11820 #endif |
11820 } | 11821 } |
11821 | 11822 |
11822 } } // namespace v8::internal | 11823 } } // namespace v8::internal |
OLD | NEW |