| OLD | NEW |
| 1 // Copyright 2015 the V8 project authors. All rights reserved. | 1 // Copyright 2015 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 "src/objects.h" | 5 #include "src/objects.h" |
| 6 | 6 |
| 7 #include <cmath> | 7 #include <cmath> |
| 8 #include <iomanip> | 8 #include <iomanip> |
| 9 #include <memory> | 9 #include <memory> |
| 10 #include <sstream> | 10 #include <sstream> |
| (...skipping 15469 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15480 while (current->IsAllocationSite()) { | 15480 while (current->IsAllocationSite()) { |
| 15481 AllocationSite* current_site = AllocationSite::cast(current); | 15481 AllocationSite* current_site = AllocationSite::cast(current); |
| 15482 if (current_site->nested_site() == this) { | 15482 if (current_site->nested_site() == this) { |
| 15483 return true; | 15483 return true; |
| 15484 } | 15484 } |
| 15485 current = current_site->weak_next(); | 15485 current = current_site->weak_next(); |
| 15486 } | 15486 } |
| 15487 return false; | 15487 return false; |
| 15488 } | 15488 } |
| 15489 | 15489 |
| 15490 | 15490 template <AllocationSiteUpdateMode update_or_check> |
| 15491 void AllocationSite::DigestTransitionFeedback(Handle<AllocationSite> site, | 15491 bool AllocationSite::DigestTransitionFeedback(Handle<AllocationSite> site, |
| 15492 ElementsKind to_kind) { | 15492 ElementsKind to_kind) { |
| 15493 Isolate* isolate = site->GetIsolate(); | 15493 Isolate* isolate = site->GetIsolate(); |
| 15494 bool result = false; |
| 15494 | 15495 |
| 15495 if (site->SitePointsToLiteral() && site->transition_info()->IsJSArray()) { | 15496 if (site->SitePointsToLiteral() && site->transition_info()->IsJSArray()) { |
| 15496 Handle<JSArray> transition_info = | 15497 Handle<JSArray> transition_info = |
| 15497 handle(JSArray::cast(site->transition_info())); | 15498 handle(JSArray::cast(site->transition_info())); |
| 15498 ElementsKind kind = transition_info->GetElementsKind(); | 15499 ElementsKind kind = transition_info->GetElementsKind(); |
| 15499 // if kind is holey ensure that to_kind is as well. | 15500 // if kind is holey ensure that to_kind is as well. |
| 15500 if (IsHoleyElementsKind(kind)) { | 15501 if (IsHoleyElementsKind(kind)) { |
| 15501 to_kind = GetHoleyElementsKind(to_kind); | 15502 to_kind = GetHoleyElementsKind(to_kind); |
| 15502 } | 15503 } |
| 15503 if (IsMoreGeneralElementsKindTransition(kind, to_kind)) { | 15504 if (IsMoreGeneralElementsKindTransition(kind, to_kind)) { |
| 15504 // If the array is huge, it's not likely to be defined in a local | 15505 // If the array is huge, it's not likely to be defined in a local |
| 15505 // function, so we shouldn't make new instances of it very often. | 15506 // function, so we shouldn't make new instances of it very often. |
| 15506 uint32_t length = 0; | 15507 uint32_t length = 0; |
| 15507 CHECK(transition_info->length()->ToArrayLength(&length)); | 15508 CHECK(transition_info->length()->ToArrayLength(&length)); |
| 15508 if (length <= kMaximumArrayBytesToPretransition) { | 15509 if (length <= kMaximumArrayBytesToPretransition) { |
| 15510 if (update_or_check == AllocationSiteUpdateMode::kCheckOnly) { |
| 15511 return true; |
| 15512 } |
| 15509 if (FLAG_trace_track_allocation_sites) { | 15513 if (FLAG_trace_track_allocation_sites) { |
| 15510 bool is_nested = site->IsNestedSite(); | 15514 bool is_nested = site->IsNestedSite(); |
| 15511 PrintF( | 15515 PrintF( |
| 15512 "AllocationSite: JSArray %p boilerplate %s updated %s->%s\n", | 15516 "AllocationSite: JSArray %p boilerplate %s updated %s->%s\n", |
| 15513 reinterpret_cast<void*>(*site), | 15517 reinterpret_cast<void*>(*site), |
| 15514 is_nested ? "(nested)" : "", | 15518 is_nested ? "(nested)" : "", |
| 15515 ElementsKindToString(kind), | 15519 ElementsKindToString(kind), |
| 15516 ElementsKindToString(to_kind)); | 15520 ElementsKindToString(to_kind)); |
| 15517 } | 15521 } |
| 15518 JSObject::TransitionElementsKind(transition_info, to_kind); | 15522 JSObject::TransitionElementsKind(transition_info, to_kind); |
| 15519 site->dependent_code()->DeoptimizeDependentCodeGroup( | 15523 site->dependent_code()->DeoptimizeDependentCodeGroup( |
| 15520 isolate, DependentCode::kAllocationSiteTransitionChangedGroup); | 15524 isolate, DependentCode::kAllocationSiteTransitionChangedGroup); |
| 15525 result = true; |
| 15521 } | 15526 } |
| 15522 } | 15527 } |
| 15523 } else { | 15528 } else { |
| 15524 ElementsKind kind = site->GetElementsKind(); | 15529 ElementsKind kind = site->GetElementsKind(); |
| 15525 // if kind is holey ensure that to_kind is as well. | 15530 // if kind is holey ensure that to_kind is as well. |
| 15526 if (IsHoleyElementsKind(kind)) { | 15531 if (IsHoleyElementsKind(kind)) { |
| 15527 to_kind = GetHoleyElementsKind(to_kind); | 15532 to_kind = GetHoleyElementsKind(to_kind); |
| 15528 } | 15533 } |
| 15529 if (IsMoreGeneralElementsKindTransition(kind, to_kind)) { | 15534 if (IsMoreGeneralElementsKindTransition(kind, to_kind)) { |
| 15535 if (update_or_check == AllocationSiteUpdateMode::kCheckOnly) return true; |
| 15530 if (FLAG_trace_track_allocation_sites) { | 15536 if (FLAG_trace_track_allocation_sites) { |
| 15531 PrintF("AllocationSite: JSArray %p site updated %s->%s\n", | 15537 PrintF("AllocationSite: JSArray %p site updated %s->%s\n", |
| 15532 reinterpret_cast<void*>(*site), | 15538 reinterpret_cast<void*>(*site), |
| 15533 ElementsKindToString(kind), | 15539 ElementsKindToString(kind), |
| 15534 ElementsKindToString(to_kind)); | 15540 ElementsKindToString(to_kind)); |
| 15535 } | 15541 } |
| 15536 site->SetElementsKind(to_kind); | 15542 site->SetElementsKind(to_kind); |
| 15537 site->dependent_code()->DeoptimizeDependentCodeGroup( | 15543 site->dependent_code()->DeoptimizeDependentCodeGroup( |
| 15538 isolate, DependentCode::kAllocationSiteTransitionChangedGroup); | 15544 isolate, DependentCode::kAllocationSiteTransitionChangedGroup); |
| 15545 result = true; |
| 15539 } | 15546 } |
| 15540 } | 15547 } |
| 15548 return result; |
| 15541 } | 15549 } |
| 15542 | 15550 |
| 15543 | 15551 |
| 15544 const char* AllocationSite::PretenureDecisionName(PretenureDecision decision) { | 15552 const char* AllocationSite::PretenureDecisionName(PretenureDecision decision) { |
| 15545 switch (decision) { | 15553 switch (decision) { |
| 15546 case kUndecided: return "undecided"; | 15554 case kUndecided: return "undecided"; |
| 15547 case kDontTenure: return "don't tenure"; | 15555 case kDontTenure: return "don't tenure"; |
| 15548 case kMaybeTenure: return "maybe tenure"; | 15556 case kMaybeTenure: return "maybe tenure"; |
| 15549 case kTenure: return "tenure"; | 15557 case kTenure: return "tenure"; |
| 15550 case kZombie: return "zombie"; | 15558 case kZombie: return "zombie"; |
| 15551 default: UNREACHABLE(); | 15559 default: UNREACHABLE(); |
| 15552 } | 15560 } |
| 15553 return NULL; | 15561 return NULL; |
| 15554 } | 15562 } |
| 15555 | 15563 |
| 15556 | 15564 template <AllocationSiteUpdateMode update_or_check> |
| 15557 void JSObject::UpdateAllocationSite(Handle<JSObject> object, | 15565 bool JSObject::UpdateAllocationSite(Handle<JSObject> object, |
| 15558 ElementsKind to_kind) { | 15566 ElementsKind to_kind) { |
| 15559 if (!object->IsJSArray()) return; | 15567 if (!object->IsJSArray()) return false; |
| 15560 | 15568 |
| 15561 Heap* heap = object->GetHeap(); | 15569 Heap* heap = object->GetHeap(); |
| 15562 if (!heap->InNewSpace(*object)) return; | 15570 if (!heap->InNewSpace(*object)) return false; |
| 15563 | 15571 |
| 15564 Handle<AllocationSite> site; | 15572 Handle<AllocationSite> site; |
| 15565 { | 15573 { |
| 15566 DisallowHeapAllocation no_allocation; | 15574 DisallowHeapAllocation no_allocation; |
| 15567 | 15575 |
| 15568 AllocationMemento* memento = | 15576 AllocationMemento* memento = |
| 15569 heap->FindAllocationMemento<Heap::kForRuntime>(*object); | 15577 heap->FindAllocationMemento<Heap::kForRuntime>(*object); |
| 15570 if (memento == NULL) return; | 15578 if (memento == NULL) return false; |
| 15571 | 15579 |
| 15572 // Walk through to the Allocation Site | 15580 // Walk through to the Allocation Site |
| 15573 site = handle(memento->GetAllocationSite()); | 15581 site = handle(memento->GetAllocationSite()); |
| 15574 } | 15582 } |
| 15575 AllocationSite::DigestTransitionFeedback(site, to_kind); | 15583 return AllocationSite::DigestTransitionFeedback<update_or_check>(site, |
| 15584 to_kind); |
| 15576 } | 15585 } |
| 15577 | 15586 |
| 15587 template bool |
| 15588 JSObject::UpdateAllocationSite<AllocationSiteUpdateMode::kCheckOnly>( |
| 15589 Handle<JSObject> object, ElementsKind to_kind); |
| 15590 |
| 15591 template bool JSObject::UpdateAllocationSite<AllocationSiteUpdateMode::kUpdate>( |
| 15592 Handle<JSObject> object, ElementsKind to_kind); |
| 15578 | 15593 |
| 15579 void JSObject::TransitionElementsKind(Handle<JSObject> object, | 15594 void JSObject::TransitionElementsKind(Handle<JSObject> object, |
| 15580 ElementsKind to_kind) { | 15595 ElementsKind to_kind) { |
| 15581 ElementsKind from_kind = object->GetElementsKind(); | 15596 ElementsKind from_kind = object->GetElementsKind(); |
| 15582 | 15597 |
| 15583 if (IsFastHoleyElementsKind(from_kind)) { | 15598 if (IsFastHoleyElementsKind(from_kind)) { |
| 15584 to_kind = GetHoleyElementsKind(to_kind); | 15599 to_kind = GetHoleyElementsKind(to_kind); |
| 15585 } | 15600 } |
| 15586 | 15601 |
| 15587 if (from_kind == to_kind) return; | 15602 if (from_kind == to_kind) return; |
| (...skipping 3742 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 19330 for (PrototypeIterator iter(isolate, this, kStartAtReceiver, | 19345 for (PrototypeIterator iter(isolate, this, kStartAtReceiver, |
| 19331 PrototypeIterator::END_AT_NULL); | 19346 PrototypeIterator::END_AT_NULL); |
| 19332 !iter.IsAtEnd(); iter.AdvanceIgnoringProxies()) { | 19347 !iter.IsAtEnd(); iter.AdvanceIgnoringProxies()) { |
| 19333 if (iter.GetCurrent<Object>()->IsJSProxy()) return true; | 19348 if (iter.GetCurrent<Object>()->IsJSProxy()) return true; |
| 19334 } | 19349 } |
| 19335 return false; | 19350 return false; |
| 19336 } | 19351 } |
| 19337 | 19352 |
| 19338 } // namespace internal | 19353 } // namespace internal |
| 19339 } // namespace v8 | 19354 } // namespace v8 |
| OLD | NEW |