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 5330 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5341 HObjectAccess access = info->access(); | 5341 HObjectAccess access = info->access(); |
5342 if (access.representation().IsDouble()) { | 5342 if (access.representation().IsDouble()) { |
5343 // Load the heap number. | 5343 // Load the heap number. |
5344 checked_object = Add<HLoadNamedField>( | 5344 checked_object = Add<HLoadNamedField>( |
5345 checked_object, static_cast<HValue*>(NULL), | 5345 checked_object, static_cast<HValue*>(NULL), |
5346 access.WithRepresentation(Representation::Tagged())); | 5346 access.WithRepresentation(Representation::Tagged())); |
5347 checked_object->set_type(HType::HeapNumber()); | 5347 checked_object->set_type(HType::HeapNumber()); |
5348 // Load the double value from it. | 5348 // Load the double value from it. |
5349 access = HObjectAccess::ForHeapNumberValue(); | 5349 access = HObjectAccess::ForHeapNumberValue(); |
5350 } | 5350 } |
5351 | |
5352 SmallMapList* map_list = info->field_maps(); | |
5353 if (map_list->length() == 0) { | |
5354 return New<HLoadNamedField>(checked_object, checked_object, access); | |
5355 } | |
5356 | |
5357 UniqueSet<Map>* maps = new(zone()) UniqueSet<Map>(map_list->length(), zone()); | |
5358 for (int i = 0; i < map_list->length(); ++i) { | |
5359 Handle<Map> map = map_list->at(i); | |
5360 maps->Add(Unique<Map>::CreateImmovable(map), zone()); | |
5361 // TODO(bmeurer): Get rid of this shit! | |
5362 if (map->CanTransition()) { | |
5363 Map::AddDependentCompilationInfo( | |
5364 map, DependentCode::kPrototypeCheckGroup, top_info()); | |
5365 } | |
5366 } | |
5351 return New<HLoadNamedField>( | 5367 return New<HLoadNamedField>( |
5352 checked_object, checked_object, access, info->field_maps(), top_info()); | 5368 checked_object, checked_object, access, maps, info->field_type()); |
5353 } | 5369 } |
5354 | 5370 |
5355 | 5371 |
5356 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( | 5372 HInstruction* HOptimizedGraphBuilder::BuildStoreNamedField( |
5357 PropertyAccessInfo* info, | 5373 PropertyAccessInfo* info, |
5358 HValue* checked_object, | 5374 HValue* checked_object, |
5359 HValue* value) { | 5375 HValue* value) { |
5360 bool transition_to_field = info->lookup()->IsTransition(); | 5376 bool transition_to_field = info->lookup()->IsTransition(); |
5361 // TODO(verwaest): Move this logic into PropertyAccessInfo. | 5377 // TODO(verwaest): Move this logic into PropertyAccessInfo. |
5362 HObjectAccess field_access = info->access(); | 5378 HObjectAccess field_access = info->access(); |
(...skipping 118 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5481 // We can only merge stores that agree on their field maps. The comparison | 5497 // We can only merge stores that agree on their field maps. The comparison |
5482 // below is safe, since we keep the field maps sorted. | 5498 // below is safe, since we keep the field maps sorted. |
5483 if (field_maps_.length() != info->field_maps_.length()) return false; | 5499 if (field_maps_.length() != info->field_maps_.length()) return false; |
5484 for (int i = 0; i < field_maps_.length(); ++i) { | 5500 for (int i = 0; i < field_maps_.length(); ++i) { |
5485 if (!field_maps_.at(i).is_identical_to(info->field_maps_.at(i))) { | 5501 if (!field_maps_.at(i).is_identical_to(info->field_maps_.at(i))) { |
5486 return false; | 5502 return false; |
5487 } | 5503 } |
5488 } | 5504 } |
5489 } | 5505 } |
5490 info->GeneralizeRepresentation(r); | 5506 info->GeneralizeRepresentation(r); |
5507 info->field_type_ = info->field_type_.Combine(field_type_); | |
5491 return true; | 5508 return true; |
5492 } | 5509 } |
5493 | 5510 |
5494 | 5511 |
5495 bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupDescriptor() { | 5512 bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupDescriptor() { |
5496 if (!type_->IsClass()) return true; | 5513 if (!type_->IsClass()) return true; |
5497 map()->LookupDescriptor(NULL, *name_, &lookup_); | 5514 map()->LookupDescriptor(NULL, *name_, &lookup_); |
5498 return LoadResult(map()); | 5515 return LoadResult(map()); |
5499 } | 5516 } |
5500 | 5517 |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
5532 } else if (lookup_.IsConstant()) { | 5549 } else if (lookup_.IsConstant()) { |
5533 constant_ = handle(lookup_.GetConstantFromMap(*map), isolate()); | 5550 constant_ = handle(lookup_.GetConstantFromMap(*map), isolate()); |
5534 } | 5551 } |
5535 | 5552 |
5536 return true; | 5553 return true; |
5537 } | 5554 } |
5538 | 5555 |
5539 | 5556 |
5540 void HOptimizedGraphBuilder::PropertyAccessInfo::LoadFieldMaps( | 5557 void HOptimizedGraphBuilder::PropertyAccessInfo::LoadFieldMaps( |
5541 Handle<Map> map) { | 5558 Handle<Map> map) { |
5542 // Clear any previously collected field maps. | 5559 // Clear any previously collected field maps/type. |
5543 field_maps_.Clear(); | 5560 field_maps_.Clear(); |
5561 field_type_ = HType::Tagged(); | |
5544 | 5562 |
5545 // Figure out the field type from the accessor map. | 5563 // Figure out the field type from the accessor map. |
5546 Handle<HeapType> field_type(lookup_.GetFieldTypeFromMap(*map), isolate()); | 5564 Handle<HeapType> field_type(lookup_.GetFieldTypeFromMap(*map), isolate()); |
5547 | 5565 |
5548 // Collect the (stable) maps from the field type. | 5566 // Collect the (stable) maps from the field type. |
5549 int num_field_maps = field_type->NumClasses(); | 5567 int num_field_maps = field_type->NumClasses(); |
5550 if (num_field_maps == 0) return; | 5568 if (num_field_maps == 0) return; |
5551 ASSERT(access_.representation().IsHeapObject()); | 5569 ASSERT(access_.representation().IsHeapObject()); |
5552 field_maps_.Reserve(num_field_maps, zone()); | 5570 field_maps_.Reserve(num_field_maps, zone()); |
5553 HeapType::Iterator<Map> it = field_type->Classes(); | 5571 HeapType::Iterator<Map> it = field_type->Classes(); |
5554 while (!it.Done()) { | 5572 while (!it.Done()) { |
5555 Handle<Map> field_map = it.Current(); | 5573 Handle<Map> field_map = it.Current(); |
5556 if (!field_map->is_stable()) { | 5574 if (!field_map->is_stable()) { |
5557 field_maps_.Clear(); | 5575 field_maps_.Clear(); |
5558 return; | 5576 return; |
5559 } | 5577 } |
5560 field_maps_.Add(field_map, zone()); | 5578 field_maps_.Add(field_map, zone()); |
5561 it.Advance(); | 5579 it.Advance(); |
5562 } | 5580 } |
5563 field_maps_.Sort(); | 5581 field_maps_.Sort(); |
5564 ASSERT_EQ(num_field_maps, field_maps_.length()); | 5582 ASSERT_EQ(num_field_maps, field_maps_.length()); |
5565 | 5583 |
5584 // Determine field HType from field HeapType. | |
Sven Panne
2014/05/07 07:31:52
Does it make sense to extract this into a function
Benedikt Meurer
2014/05/07 07:47:44
I don't think so, because this is kinda special fo
| |
5585 if (field_type->Is(HeapType::Number())) { | |
5586 field_type_ = HType::HeapNumber(); | |
5587 } else if (field_type->Is(HeapType::String())) { | |
5588 field_type_ = HType::String(); | |
5589 } else if (field_type->Is(HeapType::Boolean())) { | |
5590 field_type_ = HType::Boolean(); | |
5591 } else if (field_type->Is(HeapType::Array())) { | |
5592 field_type_ = HType::JSArray(); | |
5593 } else if (field_type->Is(HeapType::Object())) { | |
5594 field_type_ = HType::JSObject(); | |
5595 } else if (field_type->Is(HeapType::Null()) || | |
5596 field_type->Is(HeapType::Undefined())) { | |
5597 field_type_ = HType::NonPrimitive(); | |
5598 } | |
5599 | |
5566 // Add dependency on the map that introduced the field. | 5600 // Add dependency on the map that introduced the field. |
5567 Map::AddDependentCompilationInfo( | 5601 Map::AddDependentCompilationInfo( |
5568 handle(lookup_.GetFieldOwnerFromMap(*map), isolate()), | 5602 handle(lookup_.GetFieldOwnerFromMap(*map), isolate()), |
5569 DependentCode::kFieldTypeGroup, top_info()); | 5603 DependentCode::kFieldTypeGroup, top_info()); |
5570 } | 5604 } |
5571 | 5605 |
5572 | 5606 |
5573 bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupInPrototypes() { | 5607 bool HOptimizedGraphBuilder::PropertyAccessInfo::LookupInPrototypes() { |
5574 Handle<Map> map = this->map(); | 5608 Handle<Map> map = this->map(); |
5575 | 5609 |
(...skipping 6063 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
11639 if (ShouldProduceTraceOutput()) { | 11673 if (ShouldProduceTraceOutput()) { |
11640 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 11674 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
11641 } | 11675 } |
11642 | 11676 |
11643 #ifdef DEBUG | 11677 #ifdef DEBUG |
11644 graph_->Verify(false); // No full verify. | 11678 graph_->Verify(false); // No full verify. |
11645 #endif | 11679 #endif |
11646 } | 11680 } |
11647 | 11681 |
11648 } } // namespace v8::internal | 11682 } } // namespace v8::internal |
OLD | NEW |