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 8847 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8858 AllocationSiteInfo* info = AllocationSiteInfo::cast( | 8858 AllocationSiteInfo* info = AllocationSiteInfo::cast( |
8859 reinterpret_cast<Object*>(ptr_end + 1)); | 8859 reinterpret_cast<Object*>(ptr_end + 1)); |
8860 return info; | 8860 return info; |
8861 } | 8861 } |
8862 } | 8862 } |
8863 } | 8863 } |
8864 return NULL; | 8864 return NULL; |
8865 } | 8865 } |
8866 | 8866 |
8867 | 8867 |
8868 bool AllocationSiteInfo::GetElementsKindPayload(ElementsKind* kind) { | |
8869 ASSERT(kind != NULL); | |
8870 if (payload()->IsCell()) { | |
8871 Cell* cell = Cell::cast(payload()); | |
8872 Object* cell_contents = cell->value(); | |
8873 if (cell_contents->IsSmi()) { | |
8874 *kind = static_cast<ElementsKind>( | |
8875 Smi::cast(cell_contents)->value()); | |
8876 return true; | |
8877 } | |
8878 } | |
8879 return false; | |
8880 } | |
8881 | |
8882 | |
8883 uint32_t StringHasher::MakeArrayIndexHash(uint32_t value, int length) { | 8868 uint32_t StringHasher::MakeArrayIndexHash(uint32_t value, int length) { |
8884 // For array indexes mix the length into the hash as an array index could | 8869 // For array indexes mix the length into the hash as an array index could |
8885 // be zero. | 8870 // be zero. |
8886 ASSERT(length > 0); | 8871 ASSERT(length > 0); |
8887 ASSERT(length <= String::kMaxArrayIndexSize); | 8872 ASSERT(length <= String::kMaxArrayIndexSize); |
8888 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) < | 8873 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) < |
8889 (1 << String::kArrayIndexValueBits)); | 8874 (1 << String::kArrayIndexValueBits)); |
8890 | 8875 |
8891 value <<= String::kHashShift; | 8876 value <<= String::kHashShift; |
8892 value |= length << String::kArrayIndexHashLengthShift; | 8877 value |= length << String::kArrayIndexHashLengthShift; |
(...skipping 1370 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
10263 | 10248 |
10264 | 10249 |
10265 void Code::ClearTypeFeedbackCells(Heap* heap) { | 10250 void Code::ClearTypeFeedbackCells(Heap* heap) { |
10266 if (kind() != FUNCTION) return; | 10251 if (kind() != FUNCTION) return; |
10267 Object* raw_info = type_feedback_info(); | 10252 Object* raw_info = type_feedback_info(); |
10268 if (raw_info->IsTypeFeedbackInfo()) { | 10253 if (raw_info->IsTypeFeedbackInfo()) { |
10269 TypeFeedbackCells* type_feedback_cells = | 10254 TypeFeedbackCells* type_feedback_cells = |
10270 TypeFeedbackInfo::cast(raw_info)->type_feedback_cells(); | 10255 TypeFeedbackInfo::cast(raw_info)->type_feedback_cells(); |
10271 for (int i = 0; i < type_feedback_cells->CellCount(); i++) { | 10256 for (int i = 0; i < type_feedback_cells->CellCount(); i++) { |
10272 Cell* cell = type_feedback_cells->GetCell(i); | 10257 Cell* cell = type_feedback_cells->GetCell(i); |
10273 cell->set_value(TypeFeedbackCells::RawUninitializedSentinel(heap)); | 10258 // Don't clear AllocationSites |
| 10259 Object* value = cell->value(); |
| 10260 if (value == NULL || !value->IsAllocationSite()) { |
| 10261 cell->set_value(TypeFeedbackCells::RawUninitializedSentinel(heap)); |
| 10262 } |
10274 } | 10263 } |
10275 } | 10264 } |
10276 } | 10265 } |
10277 | 10266 |
10278 | 10267 |
10279 bool Code::allowed_in_shared_map_code_cache() { | 10268 bool Code::allowed_in_shared_map_code_cache() { |
10280 return is_keyed_load_stub() || is_keyed_store_stub() || | 10269 return is_keyed_load_stub() || is_keyed_store_stub() || |
10281 (is_compare_ic_stub() && | 10270 (is_compare_ic_stub() && |
10282 ICCompareStub::CompareState(stub_info()) == CompareIC::KNOWN_OBJECT); | 10271 ICCompareStub::CompareState(stub_info()) == CompareIC::KNOWN_OBJECT); |
10283 } | 10272 } |
(...skipping 1444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
11728 check_prototype); | 11717 check_prototype); |
11729 } | 11718 } |
11730 } | 11719 } |
11731 // Convert to fast double elements if appropriate. | 11720 // Convert to fast double elements if appropriate. |
11732 if (HasFastSmiElements() && !value->IsSmi() && value->IsNumber()) { | 11721 if (HasFastSmiElements() && !value->IsSmi() && value->IsNumber()) { |
11733 // Consider fixing the boilerplate as well if we have one. | 11722 // Consider fixing the boilerplate as well if we have one. |
11734 ElementsKind to_kind = IsHoleyElementsKind(elements_kind) | 11723 ElementsKind to_kind = IsHoleyElementsKind(elements_kind) |
11735 ? FAST_HOLEY_DOUBLE_ELEMENTS | 11724 ? FAST_HOLEY_DOUBLE_ELEMENTS |
11736 : FAST_DOUBLE_ELEMENTS; | 11725 : FAST_DOUBLE_ELEMENTS; |
11737 | 11726 |
11738 MaybeObject* maybe_failure = UpdateAllocationSiteInfo(to_kind); | 11727 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind); |
11739 if (maybe_failure->IsFailure()) return maybe_failure; | 11728 if (maybe_failure->IsFailure()) return maybe_failure; |
11740 | 11729 |
11741 MaybeObject* maybe = | 11730 MaybeObject* maybe = |
11742 SetFastDoubleElementsCapacityAndLength(new_capacity, array_length); | 11731 SetFastDoubleElementsCapacityAndLength(new_capacity, array_length); |
11743 if (maybe->IsFailure()) return maybe; | 11732 if (maybe->IsFailure()) return maybe; |
11744 FixedDoubleArray::cast(elements())->set(index, value->Number()); | 11733 FixedDoubleArray::cast(elements())->set(index, value->Number()); |
11745 ValidateElements(); | 11734 ValidateElements(); |
11746 return value; | 11735 return value; |
11747 } | 11736 } |
11748 // Change elements kind from Smi-only to generic FAST if necessary. | 11737 // Change elements kind from Smi-only to generic FAST if necessary. |
11749 if (HasFastSmiElements() && !value->IsSmi()) { | 11738 if (HasFastSmiElements() && !value->IsSmi()) { |
11750 Map* new_map; | 11739 Map* new_map; |
11751 ElementsKind kind = HasFastHoleyElements() | 11740 ElementsKind kind = HasFastHoleyElements() |
11752 ? FAST_HOLEY_ELEMENTS | 11741 ? FAST_HOLEY_ELEMENTS |
11753 : FAST_ELEMENTS; | 11742 : FAST_ELEMENTS; |
11754 | 11743 |
11755 MaybeObject* maybe_failure = UpdateAllocationSiteInfo(kind); | 11744 MaybeObject* maybe_failure = UpdateAllocationSite(kind); |
11756 if (maybe_failure->IsFailure()) return maybe_failure; | 11745 if (maybe_failure->IsFailure()) return maybe_failure; |
11757 | 11746 |
11758 MaybeObject* maybe_new_map = GetElementsTransitionMap(GetIsolate(), | 11747 MaybeObject* maybe_new_map = GetElementsTransitionMap(GetIsolate(), |
11759 kind); | 11748 kind); |
11760 if (!maybe_new_map->To(&new_map)) return maybe_new_map; | 11749 if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
11761 | 11750 |
11762 set_map(new_map); | 11751 set_map(new_map); |
11763 } | 11752 } |
11764 // Increase backing store capacity if that's been decided previously. | 11753 // Increase backing store capacity if that's been decided previously. |
11765 if (new_capacity != capacity) { | 11754 if (new_capacity != capacity) { |
(...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
12308 | 12297 |
12309 | 12298 |
12310 Handle<Object> JSObject::TransitionElementsKind(Handle<JSObject> object, | 12299 Handle<Object> JSObject::TransitionElementsKind(Handle<JSObject> object, |
12311 ElementsKind to_kind) { | 12300 ElementsKind to_kind) { |
12312 CALL_HEAP_FUNCTION(object->GetIsolate(), | 12301 CALL_HEAP_FUNCTION(object->GetIsolate(), |
12313 object->TransitionElementsKind(to_kind), | 12302 object->TransitionElementsKind(to_kind), |
12314 Object); | 12303 Object); |
12315 } | 12304 } |
12316 | 12305 |
12317 | 12306 |
12318 MaybeObject* JSObject::UpdateAllocationSiteInfo(ElementsKind to_kind) { | 12307 MaybeObject* JSObject::UpdateAllocationSite(ElementsKind to_kind) { |
12319 if (!FLAG_track_allocation_sites || !IsJSArray()) { | 12308 if (!FLAG_track_allocation_sites || !IsJSArray()) { |
12320 return this; | 12309 return this; |
12321 } | 12310 } |
12322 | 12311 |
12323 AllocationSiteInfo* info = AllocationSiteInfo::FindForJSObject(this); | 12312 AllocationSiteInfo* info = AllocationSiteInfo::FindForJSObject(this); |
12324 if (info == NULL) { | 12313 if (info == NULL || !info->IsValid()) { |
12325 return this; | 12314 return this; |
12326 } | 12315 } |
12327 | 12316 |
12328 if (info->payload()->IsJSArray()) { | 12317 // Walk through to the Allocation Site |
12329 JSArray* payload = JSArray::cast(info->payload()); | 12318 AllocationSite* site = info->GetAllocationSite(); |
| 12319 if (site->IsLiteralSite()) { |
| 12320 JSArray* payload = JSArray::cast(site->payload()); |
12330 ElementsKind kind = payload->GetElementsKind(); | 12321 ElementsKind kind = payload->GetElementsKind(); |
12331 if (AllocationSiteInfo::GetMode(kind, to_kind) == TRACK_ALLOCATION_SITE) { | 12322 if (AllocationSite::GetMode(kind, to_kind) == TRACK_ALLOCATION_SITE) { |
12332 // If the array is huge, it's not likely to be defined in a local | 12323 // If the array is huge, it's not likely to be defined in a local |
12333 // function, so we shouldn't make new instances of it very often. | 12324 // function, so we shouldn't make new instances of it very often. |
12334 uint32_t length = 0; | 12325 uint32_t length = 0; |
12335 CHECK(payload->length()->ToArrayIndex(&length)); | 12326 CHECK(payload->length()->ToArrayIndex(&length)); |
12336 if (length <= AllocationSiteInfo::kMaximumArrayBytesToPretransition) { | 12327 if (length <= AllocationSite::kMaximumArrayBytesToPretransition) { |
12337 if (FLAG_trace_track_allocation_sites) { | 12328 if (FLAG_trace_track_allocation_sites) { |
12338 PrintF( | 12329 PrintF( |
12339 "AllocationSiteInfo: JSArray %p boilerplate updated %s->%s\n", | 12330 "AllocationSite: JSArray %p boilerplate updated %s->%s\n", |
12340 reinterpret_cast<void*>(this), | 12331 reinterpret_cast<void*>(this), |
12341 ElementsKindToString(kind), | 12332 ElementsKindToString(kind), |
12342 ElementsKindToString(to_kind)); | 12333 ElementsKindToString(to_kind)); |
12343 } | 12334 } |
12344 return payload->TransitionElementsKind(to_kind); | 12335 return payload->TransitionElementsKind(to_kind); |
12345 } | 12336 } |
12346 } | 12337 } |
12347 } else if (info->payload()->IsCell()) { | 12338 } else { |
12348 Cell* cell = Cell::cast(info->payload()); | 12339 ElementsKind kind = site->GetElementsKindPayload(); |
12349 Object* cell_contents = cell->value(); | 12340 if (AllocationSite::GetMode(kind, to_kind) == TRACK_ALLOCATION_SITE) { |
12350 if (cell_contents->IsSmi()) { | 12341 if (FLAG_trace_track_allocation_sites) { |
12351 ElementsKind kind = static_cast<ElementsKind>( | 12342 PrintF("AllocationSite: JSArray %p site updated %s->%s\n", |
12352 Smi::cast(cell_contents)->value()); | 12343 reinterpret_cast<void*>(this), |
12353 if (AllocationSiteInfo::GetMode(kind, to_kind) == TRACK_ALLOCATION_SITE) { | 12344 ElementsKindToString(kind), |
12354 if (FLAG_trace_track_allocation_sites) { | 12345 ElementsKindToString(to_kind)); |
12355 PrintF("AllocationSiteInfo: JSArray %p info updated %s->%s\n", | |
12356 reinterpret_cast<void*>(this), | |
12357 ElementsKindToString(kind), | |
12358 ElementsKindToString(to_kind)); | |
12359 } | |
12360 cell->set_value(Smi::FromInt(to_kind)); | |
12361 } | 12346 } |
| 12347 site->set_payload(Smi::FromInt(to_kind)); |
12362 } | 12348 } |
12363 } | 12349 } |
12364 return this; | 12350 return this; |
12365 } | 12351 } |
12366 | 12352 |
12367 | 12353 |
12368 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) { | 12354 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) { |
12369 ASSERT(!map()->is_observed()); | 12355 ASSERT(!map()->is_observed()); |
12370 ElementsKind from_kind = map()->elements_kind(); | 12356 ElementsKind from_kind = map()->elements_kind(); |
12371 | 12357 |
12372 if (IsFastHoleyElementsKind(from_kind)) { | 12358 if (IsFastHoleyElementsKind(from_kind)) { |
12373 to_kind = GetHoleyElementsKind(to_kind); | 12359 to_kind = GetHoleyElementsKind(to_kind); |
12374 } | 12360 } |
12375 | 12361 |
12376 if (from_kind == to_kind) return this; | 12362 if (from_kind == to_kind) return this; |
12377 | 12363 |
12378 MaybeObject* maybe_failure = UpdateAllocationSiteInfo(to_kind); | 12364 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind); |
12379 if (maybe_failure->IsFailure()) return maybe_failure; | 12365 if (maybe_failure->IsFailure()) return maybe_failure; |
12380 | 12366 |
12381 Isolate* isolate = GetIsolate(); | 12367 Isolate* isolate = GetIsolate(); |
12382 if (elements() == isolate->heap()->empty_fixed_array() || | 12368 if (elements() == isolate->heap()->empty_fixed_array() || |
12383 (IsFastSmiOrObjectElementsKind(from_kind) && | 12369 (IsFastSmiOrObjectElementsKind(from_kind) && |
12384 IsFastSmiOrObjectElementsKind(to_kind)) || | 12370 IsFastSmiOrObjectElementsKind(to_kind)) || |
12385 (from_kind == FAST_DOUBLE_ELEMENTS && | 12371 (from_kind == FAST_DOUBLE_ELEMENTS && |
12386 to_kind == FAST_HOLEY_DOUBLE_ELEMENTS)) { | 12372 to_kind == FAST_HOLEY_DOUBLE_ELEMENTS)) { |
12387 ASSERT(from_kind != TERMINAL_FAST_ELEMENTS_KIND); | 12373 ASSERT(from_kind != TERMINAL_FAST_ELEMENTS_KIND); |
12388 // No change is needed to the elements() buffer, the transition | 12374 // No change is needed to the elements() buffer, the transition |
(...skipping 3497 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
15886 | 15872 |
15887 void PropertyCell::AddDependentCode(Handle<Code> code) { | 15873 void PropertyCell::AddDependentCode(Handle<Code> code) { |
15888 Handle<DependentCode> codes = DependentCode::Insert( | 15874 Handle<DependentCode> codes = DependentCode::Insert( |
15889 Handle<DependentCode>(dependent_code()), | 15875 Handle<DependentCode>(dependent_code()), |
15890 DependentCode::kPropertyCellChangedGroup, code); | 15876 DependentCode::kPropertyCellChangedGroup, code); |
15891 if (*codes != dependent_code()) set_dependent_code(*codes); | 15877 if (*codes != dependent_code()) set_dependent_code(*codes); |
15892 } | 15878 } |
15893 | 15879 |
15894 | 15880 |
15895 } } // namespace v8::internal | 15881 } } // namespace v8::internal |
OLD | NEW |