| 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 8884 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8895 AllocationSiteInfo* info = AllocationSiteInfo::cast( | 8895 AllocationSiteInfo* info = AllocationSiteInfo::cast( |
| 8896 reinterpret_cast<Object*>(ptr_end + 1)); | 8896 reinterpret_cast<Object*>(ptr_end + 1)); |
| 8897 return info; | 8897 return info; |
| 8898 } | 8898 } |
| 8899 } | 8899 } |
| 8900 } | 8900 } |
| 8901 return NULL; | 8901 return NULL; |
| 8902 } | 8902 } |
| 8903 | 8903 |
| 8904 | 8904 |
| 8905 bool AllocationSiteInfo::GetElementsKindPayload(ElementsKind* kind) { | |
| 8906 ASSERT(kind != NULL); | |
| 8907 if (payload()->IsJSGlobalPropertyCell()) { | |
| 8908 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(payload()); | |
| 8909 Object* cell_contents = cell->value(); | |
| 8910 if (cell_contents->IsSmi()) { | |
| 8911 *kind = static_cast<ElementsKind>( | |
| 8912 Smi::cast(cell_contents)->value()); | |
| 8913 return true; | |
| 8914 } | |
| 8915 } | |
| 8916 return false; | |
| 8917 } | |
| 8918 | |
| 8919 | |
| 8920 uint32_t StringHasher::MakeArrayIndexHash(uint32_t value, int length) { | 8905 uint32_t StringHasher::MakeArrayIndexHash(uint32_t value, int length) { |
| 8921 // For array indexes mix the length into the hash as an array index could | 8906 // For array indexes mix the length into the hash as an array index could |
| 8922 // be zero. | 8907 // be zero. |
| 8923 ASSERT(length > 0); | 8908 ASSERT(length > 0); |
| 8924 ASSERT(length <= String::kMaxArrayIndexSize); | 8909 ASSERT(length <= String::kMaxArrayIndexSize); |
| 8925 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) < | 8910 ASSERT(TenToThe(String::kMaxCachedArrayIndexLength) < |
| 8926 (1 << String::kArrayIndexValueBits)); | 8911 (1 << String::kArrayIndexValueBits)); |
| 8927 | 8912 |
| 8928 value <<= String::kHashShift; | 8913 value <<= String::kHashShift; |
| 8929 value |= length << String::kArrayIndexHashLengthShift; | 8914 value |= length << String::kArrayIndexHashLengthShift; |
| (...skipping 1309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10239 | 10224 |
| 10240 | 10225 |
| 10241 void Code::ClearTypeFeedbackCells(Heap* heap) { | 10226 void Code::ClearTypeFeedbackCells(Heap* heap) { |
| 10242 if (kind() != FUNCTION) return; | 10227 if (kind() != FUNCTION) return; |
| 10243 Object* raw_info = type_feedback_info(); | 10228 Object* raw_info = type_feedback_info(); |
| 10244 if (raw_info->IsTypeFeedbackInfo()) { | 10229 if (raw_info->IsTypeFeedbackInfo()) { |
| 10245 TypeFeedbackCells* type_feedback_cells = | 10230 TypeFeedbackCells* type_feedback_cells = |
| 10246 TypeFeedbackInfo::cast(raw_info)->type_feedback_cells(); | 10231 TypeFeedbackInfo::cast(raw_info)->type_feedback_cells(); |
| 10247 for (int i = 0; i < type_feedback_cells->CellCount(); i++) { | 10232 for (int i = 0; i < type_feedback_cells->CellCount(); i++) { |
| 10248 JSGlobalPropertyCell* cell = type_feedback_cells->Cell(i); | 10233 JSGlobalPropertyCell* cell = type_feedback_cells->Cell(i); |
| 10249 cell->set_value(TypeFeedbackCells::RawUninitializedSentinel(heap)); | 10234 // Don't clear AllocationSites |
| 10235 Object* value = cell->value(); |
| 10236 if (value == NULL || !value->IsAllocationSite()) { |
| 10237 cell->set_value(TypeFeedbackCells::RawUninitializedSentinel(heap)); |
| 10238 } |
| 10250 } | 10239 } |
| 10251 } | 10240 } |
| 10252 } | 10241 } |
| 10253 | 10242 |
| 10254 | 10243 |
| 10255 bool Code::allowed_in_shared_map_code_cache() { | 10244 bool Code::allowed_in_shared_map_code_cache() { |
| 10256 return is_keyed_load_stub() || is_keyed_store_stub() || | 10245 return is_keyed_load_stub() || is_keyed_store_stub() || |
| 10257 (is_compare_ic_stub() && | 10246 (is_compare_ic_stub() && |
| 10258 ICCompareStub::CompareState(stub_info()) == CompareIC::KNOWN_OBJECT); | 10247 ICCompareStub::CompareState(stub_info()) == CompareIC::KNOWN_OBJECT); |
| 10259 } | 10248 } |
| (...skipping 1359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11619 check_prototype); | 11608 check_prototype); |
| 11620 } | 11609 } |
| 11621 } | 11610 } |
| 11622 // Convert to fast double elements if appropriate. | 11611 // Convert to fast double elements if appropriate. |
| 11623 if (HasFastSmiElements() && !value->IsSmi() && value->IsNumber()) { | 11612 if (HasFastSmiElements() && !value->IsSmi() && value->IsNumber()) { |
| 11624 // Consider fixing the boilerplate as well if we have one. | 11613 // Consider fixing the boilerplate as well if we have one. |
| 11625 ElementsKind to_kind = IsHoleyElementsKind(elements_kind) | 11614 ElementsKind to_kind = IsHoleyElementsKind(elements_kind) |
| 11626 ? FAST_HOLEY_DOUBLE_ELEMENTS | 11615 ? FAST_HOLEY_DOUBLE_ELEMENTS |
| 11627 : FAST_DOUBLE_ELEMENTS; | 11616 : FAST_DOUBLE_ELEMENTS; |
| 11628 | 11617 |
| 11629 MaybeObject* maybe_failure = UpdateAllocationSiteInfo(to_kind); | 11618 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind); |
| 11630 if (maybe_failure->IsFailure()) return maybe_failure; | 11619 if (maybe_failure->IsFailure()) return maybe_failure; |
| 11631 | 11620 |
| 11632 MaybeObject* maybe = | 11621 MaybeObject* maybe = |
| 11633 SetFastDoubleElementsCapacityAndLength(new_capacity, array_length); | 11622 SetFastDoubleElementsCapacityAndLength(new_capacity, array_length); |
| 11634 if (maybe->IsFailure()) return maybe; | 11623 if (maybe->IsFailure()) return maybe; |
| 11635 FixedDoubleArray::cast(elements())->set(index, value->Number()); | 11624 FixedDoubleArray::cast(elements())->set(index, value->Number()); |
| 11636 ValidateElements(); | 11625 ValidateElements(); |
| 11637 return value; | 11626 return value; |
| 11638 } | 11627 } |
| 11639 // Change elements kind from Smi-only to generic FAST if necessary. | 11628 // Change elements kind from Smi-only to generic FAST if necessary. |
| 11640 if (HasFastSmiElements() && !value->IsSmi()) { | 11629 if (HasFastSmiElements() && !value->IsSmi()) { |
| 11641 Map* new_map; | 11630 Map* new_map; |
| 11642 ElementsKind kind = HasFastHoleyElements() | 11631 ElementsKind kind = HasFastHoleyElements() |
| 11643 ? FAST_HOLEY_ELEMENTS | 11632 ? FAST_HOLEY_ELEMENTS |
| 11644 : FAST_ELEMENTS; | 11633 : FAST_ELEMENTS; |
| 11645 | 11634 |
| 11646 MaybeObject* maybe_failure = UpdateAllocationSiteInfo(kind); | 11635 MaybeObject* maybe_failure = UpdateAllocationSite(kind); |
| 11647 if (maybe_failure->IsFailure()) return maybe_failure; | 11636 if (maybe_failure->IsFailure()) return maybe_failure; |
| 11648 | 11637 |
| 11649 MaybeObject* maybe_new_map = GetElementsTransitionMap(GetIsolate(), | 11638 MaybeObject* maybe_new_map = GetElementsTransitionMap(GetIsolate(), |
| 11650 kind); | 11639 kind); |
| 11651 if (!maybe_new_map->To(&new_map)) return maybe_new_map; | 11640 if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
| 11652 | 11641 |
| 11653 set_map(new_map); | 11642 set_map(new_map); |
| 11654 } | 11643 } |
| 11655 // Increase backing store capacity if that's been decided previously. | 11644 // Increase backing store capacity if that's been decided previously. |
| 11656 if (new_capacity != capacity) { | 11645 if (new_capacity != capacity) { |
| (...skipping 542 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 12199 | 12188 |
| 12200 | 12189 |
| 12201 Handle<Object> JSObject::TransitionElementsKind(Handle<JSObject> object, | 12190 Handle<Object> JSObject::TransitionElementsKind(Handle<JSObject> object, |
| 12202 ElementsKind to_kind) { | 12191 ElementsKind to_kind) { |
| 12203 CALL_HEAP_FUNCTION(object->GetIsolate(), | 12192 CALL_HEAP_FUNCTION(object->GetIsolate(), |
| 12204 object->TransitionElementsKind(to_kind), | 12193 object->TransitionElementsKind(to_kind), |
| 12205 Object); | 12194 Object); |
| 12206 } | 12195 } |
| 12207 | 12196 |
| 12208 | 12197 |
| 12209 MaybeObject* JSObject::UpdateAllocationSiteInfo(ElementsKind to_kind) { | 12198 MaybeObject* JSObject::UpdateAllocationSite(ElementsKind to_kind) { |
| 12210 if (!FLAG_track_allocation_sites || !IsJSArray()) { | 12199 if (!FLAG_track_allocation_sites || !IsJSArray()) { |
| 12211 return this; | 12200 return this; |
| 12212 } | 12201 } |
| 12213 | 12202 |
| 12214 AllocationSiteInfo* info = AllocationSiteInfo::FindForJSObject(this); | 12203 AllocationSiteInfo* info = AllocationSiteInfo::FindForJSObject(this); |
| 12215 if (info == NULL) { | 12204 if (info == NULL) { |
| 12216 return this; | 12205 return this; |
| 12217 } | 12206 } |
| 12218 | 12207 |
| 12219 if (info->payload()->IsJSArray()) { | 12208 // Walk through to the Allocation Site |
| 12220 JSArray* payload = JSArray::cast(info->payload()); | 12209 AllocationSite* site = AllocationSite::cast(info->payload()); |
| 12210 if (site->IsLiteralSite()) { |
| 12211 JSArray* payload = JSArray::cast(site->payload()); |
| 12221 ElementsKind kind = payload->GetElementsKind(); | 12212 ElementsKind kind = payload->GetElementsKind(); |
| 12222 if (AllocationSiteInfo::GetMode(kind, to_kind) == TRACK_ALLOCATION_SITE) { | 12213 if (AllocationSite::GetMode(kind, to_kind) == TRACK_ALLOCATION_SITE) { |
| 12223 // If the array is huge, it's not likely to be defined in a local | 12214 // If the array is huge, it's not likely to be defined in a local |
| 12224 // function, so we shouldn't make new instances of it very often. | 12215 // function, so we shouldn't make new instances of it very often. |
| 12225 uint32_t length = 0; | 12216 uint32_t length = 0; |
| 12226 CHECK(payload->length()->ToArrayIndex(&length)); | 12217 CHECK(payload->length()->ToArrayIndex(&length)); |
| 12227 if (length <= AllocationSiteInfo::kMaximumArrayBytesToPretransition) { | 12218 if (length <= AllocationSite::kMaximumArrayBytesToPretransition) { |
| 12228 if (FLAG_trace_track_allocation_sites) { | 12219 if (FLAG_trace_track_allocation_sites) { |
| 12229 PrintF( | 12220 PrintF( |
| 12230 "AllocationSiteInfo: JSArray %p boilerplate updated %s->%s\n", | 12221 "AllocationSite: JSArray %p boilerplate updated %s->%s\n", |
| 12231 reinterpret_cast<void*>(this), | 12222 reinterpret_cast<void*>(this), |
| 12232 ElementsKindToString(kind), | 12223 ElementsKindToString(kind), |
| 12233 ElementsKindToString(to_kind)); | 12224 ElementsKindToString(to_kind)); |
| 12234 } | 12225 } |
| 12235 return payload->TransitionElementsKind(to_kind); | 12226 return payload->TransitionElementsKind(to_kind); |
| 12236 } | 12227 } |
| 12237 } | 12228 } |
| 12238 } else if (info->payload()->IsJSGlobalPropertyCell()) { | 12229 } else { |
| 12239 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(info->payload()); | 12230 ElementsKind kind = site->GetElementsKindPayload(); |
| 12240 Object* cell_contents = cell->value(); | 12231 if (AllocationSite::GetMode(kind, to_kind) == TRACK_ALLOCATION_SITE) { |
| 12241 if (cell_contents->IsSmi()) { | 12232 if (FLAG_trace_track_allocation_sites) { |
| 12242 ElementsKind kind = static_cast<ElementsKind>( | 12233 PrintF("AllocationSite: JSArray %p site updated %s->%s\n", |
| 12243 Smi::cast(cell_contents)->value()); | 12234 reinterpret_cast<void*>(this), |
| 12244 if (AllocationSiteInfo::GetMode(kind, to_kind) == TRACK_ALLOCATION_SITE) { | 12235 ElementsKindToString(kind), |
| 12245 if (FLAG_trace_track_allocation_sites) { | 12236 ElementsKindToString(to_kind)); |
| 12246 PrintF("AllocationSiteInfo: JSArray %p info updated %s->%s\n", | |
| 12247 reinterpret_cast<void*>(this), | |
| 12248 ElementsKindToString(kind), | |
| 12249 ElementsKindToString(to_kind)); | |
| 12250 } | |
| 12251 cell->set_value(Smi::FromInt(to_kind)); | |
| 12252 } | 12237 } |
| 12238 site->set_payload(Smi::FromInt(to_kind)); |
| 12253 } | 12239 } |
| 12254 } | 12240 } |
| 12255 return this; | 12241 return this; |
| 12256 } | 12242 } |
| 12257 | 12243 |
| 12258 | 12244 |
| 12259 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) { | 12245 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) { |
| 12260 ASSERT(!map()->is_observed()); | 12246 ASSERT(!map()->is_observed()); |
| 12261 ElementsKind from_kind = map()->elements_kind(); | 12247 ElementsKind from_kind = map()->elements_kind(); |
| 12262 | 12248 |
| 12263 if (IsFastHoleyElementsKind(from_kind)) { | 12249 if (IsFastHoleyElementsKind(from_kind)) { |
| 12264 to_kind = GetHoleyElementsKind(to_kind); | 12250 to_kind = GetHoleyElementsKind(to_kind); |
| 12265 } | 12251 } |
| 12266 | 12252 |
| 12267 if (from_kind == to_kind) return this; | 12253 if (from_kind == to_kind) return this; |
| 12268 | 12254 |
| 12269 MaybeObject* maybe_failure = UpdateAllocationSiteInfo(to_kind); | 12255 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind); |
| 12270 if (maybe_failure->IsFailure()) return maybe_failure; | 12256 if (maybe_failure->IsFailure()) return maybe_failure; |
| 12271 | 12257 |
| 12272 Isolate* isolate = GetIsolate(); | 12258 Isolate* isolate = GetIsolate(); |
| 12273 if (elements() == isolate->heap()->empty_fixed_array() || | 12259 if (elements() == isolate->heap()->empty_fixed_array() || |
| 12274 (IsFastSmiOrObjectElementsKind(from_kind) && | 12260 (IsFastSmiOrObjectElementsKind(from_kind) && |
| 12275 IsFastSmiOrObjectElementsKind(to_kind)) || | 12261 IsFastSmiOrObjectElementsKind(to_kind)) || |
| 12276 (from_kind == FAST_DOUBLE_ELEMENTS && | 12262 (from_kind == FAST_DOUBLE_ELEMENTS && |
| 12277 to_kind == FAST_HOLEY_DOUBLE_ELEMENTS)) { | 12263 to_kind == FAST_HOLEY_DOUBLE_ELEMENTS)) { |
| 12278 ASSERT(from_kind != TERMINAL_FAST_ELEMENTS_KIND); | 12264 ASSERT(from_kind != TERMINAL_FAST_ELEMENTS_KIND); |
| 12279 // No change is needed to the elements() buffer, the transition | 12265 // No change is needed to the elements() buffer, the transition |
| (...skipping 3408 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 15688 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); | 15674 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); |
| 15689 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); | 15675 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); |
| 15690 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); | 15676 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); |
| 15691 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); | 15677 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); |
| 15692 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); | 15678 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); |
| 15693 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); | 15679 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); |
| 15694 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); | 15680 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); |
| 15695 } | 15681 } |
| 15696 | 15682 |
| 15697 } } // namespace v8::internal | 15683 } } // namespace v8::internal |
| OLD | NEW |