Chromium Code Reviews| 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 9332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 9343 } | 9343 } |
| 9344 | 9344 |
| 9345 if (IsJSArray()) { | 9345 if (IsJSArray()) { |
| 9346 JSArray::cast(this)->set_length(Smi::FromInt(length)); | 9346 JSArray::cast(this)->set_length(Smi::FromInt(length)); |
| 9347 } | 9347 } |
| 9348 | 9348 |
| 9349 return this; | 9349 return this; |
| 9350 } | 9350 } |
| 9351 | 9351 |
| 9352 | 9352 |
| 9353 MaybeObject* JSArray::Initialize(int capacity) { | 9353 MaybeObject* JSArray::Initialize(int capacity, int length) { |
| 9354 Heap* heap = GetHeap(); | |
| 9355 ASSERT(capacity >= 0); | 9354 ASSERT(capacity >= 0); |
| 9356 set_length(Smi::FromInt(0)); | 9355 return GetHeap()->AllocateJSArrayStorage(this, length, capacity, |
| 9357 FixedArrayBase* new_elements; | 9356 INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE); |
| 9358 if (capacity == 0) { | |
| 9359 new_elements = heap->empty_fixed_array(); | |
| 9360 } else { | |
| 9361 ElementsKind elements_kind = GetElementsKind(); | |
| 9362 MaybeObject* maybe_obj; | |
| 9363 if (IsFastDoubleElementsKind(elements_kind)) { | |
| 9364 maybe_obj = heap->AllocateFixedDoubleArrayWithHoles(capacity); | |
| 9365 } else { | |
| 9366 maybe_obj = heap->AllocateFixedArrayWithHoles(capacity); | |
| 9367 } | |
| 9368 if (!maybe_obj->To(&new_elements)) return maybe_obj; | |
| 9369 } | |
| 9370 set_elements(new_elements); | |
| 9371 return this; | |
| 9372 } | 9357 } |
| 9373 | 9358 |
| 9374 | 9359 |
| 9375 void JSArray::Expand(int required_size) { | 9360 void JSArray::Expand(int required_size) { |
| 9376 GetIsolate()->factory()->SetElementsCapacityAndLength( | 9361 GetIsolate()->factory()->SetElementsCapacityAndLength( |
| 9377 Handle<JSArray>(this), required_size, required_size); | 9362 Handle<JSArray>(this), required_size, required_size); |
| 9378 } | 9363 } |
| 9379 | 9364 |
| 9380 | 9365 |
| 9381 // Returns false if the passed-in index is marked non-configurable, | 9366 // Returns false if the passed-in index is marked non-configurable, |
| (...skipping 659 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10041 check_prototype); | 10026 check_prototype); |
| 10042 } | 10027 } |
| 10043 } | 10028 } |
| 10044 // Convert to fast double elements if appropriate. | 10029 // Convert to fast double elements if appropriate. |
| 10045 if (HasFastSmiElements() && !value->IsSmi() && value->IsNumber()) { | 10030 if (HasFastSmiElements() && !value->IsSmi() && value->IsNumber()) { |
| 10046 // Consider fixing the boilerplate as well if we have one. | 10031 // Consider fixing the boilerplate as well if we have one. |
| 10047 ElementsKind to_kind = IsHoleyElementsKind(elements_kind) | 10032 ElementsKind to_kind = IsHoleyElementsKind(elements_kind) |
| 10048 ? FAST_HOLEY_DOUBLE_ELEMENTS | 10033 ? FAST_HOLEY_DOUBLE_ELEMENTS |
| 10049 : FAST_DOUBLE_ELEMENTS; | 10034 : FAST_DOUBLE_ELEMENTS; |
| 10050 | 10035 |
| 10051 MaybeObject* trans = PossiblyTransitionArrayBoilerplate(to_kind); | 10036 MaybeObject* trans = UpdateAllocationSiteInfo(to_kind); |
| 10052 if (trans->IsFailure()) return trans; | 10037 if (trans->IsFailure()) return trans; |
|
Toon Verwaest
2013/02/21 12:13:03
MaybeObject* maybe_failure = ...;
if (maybe_failur
| |
| 10053 | 10038 |
| 10054 MaybeObject* maybe = | 10039 MaybeObject* maybe = |
| 10055 SetFastDoubleElementsCapacityAndLength(new_capacity, array_length); | 10040 SetFastDoubleElementsCapacityAndLength(new_capacity, array_length); |
| 10056 if (maybe->IsFailure()) return maybe; | 10041 if (maybe->IsFailure()) return maybe; |
| 10057 FixedDoubleArray::cast(elements())->set(index, value->Number()); | 10042 FixedDoubleArray::cast(elements())->set(index, value->Number()); |
| 10058 ValidateElements(); | 10043 ValidateElements(); |
| 10059 return value; | 10044 return value; |
| 10060 } | 10045 } |
| 10061 // Change elements kind from Smi-only to generic FAST if necessary. | 10046 // Change elements kind from Smi-only to generic FAST if necessary. |
| 10062 if (HasFastSmiElements() && !value->IsSmi()) { | 10047 if (HasFastSmiElements() && !value->IsSmi()) { |
| 10063 Map* new_map; | 10048 Map* new_map; |
| 10064 ElementsKind kind = HasFastHoleyElements() | 10049 ElementsKind kind = HasFastHoleyElements() |
| 10065 ? FAST_HOLEY_ELEMENTS | 10050 ? FAST_HOLEY_ELEMENTS |
| 10066 : FAST_ELEMENTS; | 10051 : FAST_ELEMENTS; |
| 10067 | 10052 |
| 10068 MaybeObject* trans = PossiblyTransitionArrayBoilerplate(kind); | 10053 MaybeObject* trans = UpdateAllocationSiteInfo(kind); |
|
Toon Verwaest
2013/02/21 12:13:03
MaybeObject* maybe_failure = ...;
if (maybe_failur
| |
| 10069 if (trans->IsFailure()) return trans; | 10054 if (trans->IsFailure()) return trans; |
| 10070 | 10055 |
| 10071 MaybeObject* maybe_new_map = GetElementsTransitionMap(GetIsolate(), | 10056 MaybeObject* maybe_new_map = GetElementsTransitionMap(GetIsolate(), |
| 10072 kind); | 10057 kind); |
| 10073 if (!maybe_new_map->To(&new_map)) return maybe_new_map; | 10058 if (!maybe_new_map->To(&new_map)) return maybe_new_map; |
| 10074 | 10059 |
| 10075 set_map(new_map); | 10060 set_map(new_map); |
| 10076 } | 10061 } |
| 10077 // Increase backing store capacity if that's been decided previously. | 10062 // Increase backing store capacity if that's been decided previously. |
| 10078 if (new_capacity != capacity) { | 10063 if (new_capacity != capacity) { |
| (...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 10606 | 10591 |
| 10607 | 10592 |
| 10608 Handle<Object> JSObject::TransitionElementsKind(Handle<JSObject> object, | 10593 Handle<Object> JSObject::TransitionElementsKind(Handle<JSObject> object, |
| 10609 ElementsKind to_kind) { | 10594 ElementsKind to_kind) { |
| 10610 CALL_HEAP_FUNCTION(object->GetIsolate(), | 10595 CALL_HEAP_FUNCTION(object->GetIsolate(), |
| 10611 object->TransitionElementsKind(to_kind), | 10596 object->TransitionElementsKind(to_kind), |
| 10612 Object); | 10597 Object); |
| 10613 } | 10598 } |
| 10614 | 10599 |
| 10615 | 10600 |
| 10616 // TODO(mvstanton): rename this method to reflect what it actually does. | 10601 MaybeObject* JSObject::UpdateAllocationSiteInfo(ElementsKind to_kind) { |
| 10617 // If a boilerplate object is discovered, then it will transition it. | |
| 10618 // If instead there is a elements kind, then update it as long as the | |
| 10619 // to_kind variable is more general than what we find, but don't | |
| 10620 // ever take the double->fastobject transition (that represents poisoning), | |
| 10621 // just ignore that case. | |
| 10622 MaybeObject* JSObject::PossiblyTransitionArrayBoilerplate( | |
| 10623 ElementsKind to_kind) { | |
| 10624 MaybeObject* ret = NULL; | |
| 10625 if (!FLAG_track_allocation_sites || !IsJSArray()) { | 10602 if (!FLAG_track_allocation_sites || !IsJSArray()) { |
| 10626 return ret; | 10603 return NULL; |
|
Toon Verwaest
2013/02/21 12:13:03
return this;
mvstanton
2013/02/27 14:37:07
Done.
| |
| 10627 } | 10604 } |
| 10628 | 10605 |
| 10629 AllocationSiteInfo* info = AllocationSiteInfo::FindForJSObject(this); | 10606 AllocationSiteInfo* info = AllocationSiteInfo::FindForJSObject(this); |
| 10630 if (info == NULL) { | 10607 if (info == NULL) { |
| 10631 return ret; | 10608 return NULL; |
|
Toon Verwaest
2013/02/21 12:13:03
return this;
mvstanton
2013/02/27 14:37:07
Done.
| |
| 10632 } | 10609 } |
| 10633 | 10610 |
| 10634 if (info->payload()->IsJSArray()) { | 10611 if (info->payload()->IsJSArray()) { |
| 10635 JSArray* payload = JSArray::cast(info->payload()); | 10612 JSArray* payload = JSArray::cast(info->payload()); |
| 10636 ElementsKind kind = payload->GetElementsKind(); | 10613 ElementsKind kind = payload->GetElementsKind(); |
| 10637 if (IsMoreGeneralElementsKindTransition(kind, to_kind)) { | 10614 if (AllocationSiteInfo::GetMode(kind, to_kind) == TRACK_ALLOCATION_SITE) { |
| 10638 // If the array is huge, it's not likely to be defined in a local | 10615 // If the array is huge, it's not likely to be defined in a local |
| 10639 // function, so we shouldn't make new instances of it very often. | 10616 // function, so we shouldn't make new instances of it very often. |
| 10640 uint32_t length = 0; | 10617 uint32_t length = 0; |
| 10641 CHECK(payload->length()->ToArrayIndex(&length)); | 10618 CHECK(payload->length()->ToArrayIndex(&length)); |
| 10642 if (length <= 8*1024) { | 10619 if (length <= AllocationSiteInfo::kMaximumArrayBytesToPretransition) { |
| 10643 ret = payload->TransitionElementsKind(to_kind); | |
| 10644 if (FLAG_trace_track_allocation_sites) { | 10620 if (FLAG_trace_track_allocation_sites) { |
| 10645 PrintF( | 10621 PrintF( |
| 10646 "AllocationSiteInfo: JSArray %p boilerplate updated %s->%s\n", | 10622 "AllocationSiteInfo: JSArray %p boilerplate updated %s->%s\n", |
| 10647 reinterpret_cast<void*>(this), | 10623 reinterpret_cast<void*>(this), |
| 10648 ElementsKindToString(kind), | 10624 ElementsKindToString(kind), |
| 10649 ElementsKindToString(to_kind)); | 10625 ElementsKindToString(to_kind)); |
| 10650 } | 10626 } |
| 10627 return payload->TransitionElementsKind(to_kind); | |
| 10651 } | 10628 } |
| 10652 } | 10629 } |
| 10653 } else if (info->payload()->IsJSGlobalPropertyCell()) { | 10630 } else if (info->payload()->IsJSGlobalPropertyCell()) { |
| 10654 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(info->payload()); | 10631 JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(info->payload()); |
| 10655 Object* cell_contents = cell->value(); | 10632 Object* cell_contents = cell->value(); |
| 10656 if (cell_contents->IsSmi()) { | 10633 if (cell_contents->IsSmi()) { |
| 10657 ElementsKind kind = static_cast<ElementsKind>( | 10634 ElementsKind kind = static_cast<ElementsKind>( |
| 10658 Smi::cast(cell_contents)->value()); | 10635 Smi::cast(cell_contents)->value()); |
| 10659 // Specifically exclude DOUBLE(HOLEY) -> FAST(HOLEY) | 10636 if (AllocationSiteInfo::GetMode(kind, to_kind) == TRACK_ALLOCATION_SITE) { |
| 10660 bool double_to_fast = IsFastDoubleElementsKind(kind) && | |
| 10661 IsFastObjectElementsKind(to_kind); | |
| 10662 if (IsMoreGeneralElementsKindTransition(kind, to_kind) && | |
| 10663 !double_to_fast) { | |
| 10664 if (FLAG_trace_track_allocation_sites) { | 10637 if (FLAG_trace_track_allocation_sites) { |
| 10665 PrintF("AllocationSiteInfo: JSArray %p info updated %s->%s\n", | 10638 PrintF("AllocationSiteInfo: JSArray %p info updated %s->%s\n", |
| 10666 reinterpret_cast<void*>(this), | 10639 reinterpret_cast<void*>(this), |
| 10667 ElementsKindToString(kind), | 10640 ElementsKindToString(kind), |
| 10668 ElementsKindToString(to_kind)); | 10641 ElementsKindToString(to_kind)); |
| 10669 } | 10642 } |
| 10670 cell->set_value(Smi::FromInt(to_kind)); | 10643 cell->set_value(Smi::FromInt(to_kind)); |
| 10671 } | 10644 } |
| 10672 } | 10645 } |
| 10673 } | 10646 } |
| 10674 return ret; | 10647 return this; |
| 10675 } | 10648 } |
| 10676 | 10649 |
| 10677 | 10650 |
| 10678 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) { | 10651 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) { |
| 10679 ASSERT(!map()->is_observed()); | 10652 ASSERT(!map()->is_observed()); |
| 10680 ElementsKind from_kind = map()->elements_kind(); | 10653 ElementsKind from_kind = map()->elements_kind(); |
| 10681 | 10654 |
| 10682 if (IsFastHoleyElementsKind(from_kind)) { | 10655 if (IsFastHoleyElementsKind(from_kind)) { |
| 10683 to_kind = GetHoleyElementsKind(to_kind); | 10656 to_kind = GetHoleyElementsKind(to_kind); |
| 10684 } | 10657 } |
| 10685 | 10658 |
| 10686 if (from_kind == to_kind) return this; | 10659 if (from_kind == to_kind) return this; |
| 10687 | 10660 |
| 10688 MaybeObject* trans = PossiblyTransitionArrayBoilerplate(to_kind); | 10661 MaybeObject* trans = UpdateAllocationSiteInfo(to_kind); |
| 10689 if (trans->IsFailure()) return trans; | 10662 if (trans->IsFailure()) return trans; |
|
Toon Verwaest
2013/02/21 12:13:03
MaybeObject* maybe_failure = ...;
if (maybe_failur
mvstanton
2013/02/27 14:37:07
Done.
| |
| 10690 | 10663 |
| 10691 Isolate* isolate = GetIsolate(); | 10664 Isolate* isolate = GetIsolate(); |
| 10692 if (elements() == isolate->heap()->empty_fixed_array() || | 10665 if (elements() == isolate->heap()->empty_fixed_array() || |
| 10693 (IsFastSmiOrObjectElementsKind(from_kind) && | 10666 (IsFastSmiOrObjectElementsKind(from_kind) && |
| 10694 IsFastSmiOrObjectElementsKind(to_kind)) || | 10667 IsFastSmiOrObjectElementsKind(to_kind)) || |
| 10695 (from_kind == FAST_DOUBLE_ELEMENTS && | 10668 (from_kind == FAST_DOUBLE_ELEMENTS && |
| 10696 to_kind == FAST_HOLEY_DOUBLE_ELEMENTS)) { | 10669 to_kind == FAST_HOLEY_DOUBLE_ELEMENTS)) { |
| 10697 ASSERT(from_kind != TERMINAL_FAST_ELEMENTS_KIND); | 10670 ASSERT(from_kind != TERMINAL_FAST_ELEMENTS_KIND); |
| 10698 // No change is needed to the elements() buffer, the transition | 10671 // No change is needed to the elements() buffer, the transition |
| 10699 // only requires a map change. | 10672 // only requires a map change. |
| (...skipping 3332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 14032 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); | 14005 set_year(Smi::FromInt(year), SKIP_WRITE_BARRIER); |
| 14033 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); | 14006 set_month(Smi::FromInt(month), SKIP_WRITE_BARRIER); |
| 14034 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); | 14007 set_day(Smi::FromInt(day), SKIP_WRITE_BARRIER); |
| 14035 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); | 14008 set_weekday(Smi::FromInt(weekday), SKIP_WRITE_BARRIER); |
| 14036 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); | 14009 set_hour(Smi::FromInt(hour), SKIP_WRITE_BARRIER); |
| 14037 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); | 14010 set_min(Smi::FromInt(min), SKIP_WRITE_BARRIER); |
| 14038 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); | 14011 set_sec(Smi::FromInt(sec), SKIP_WRITE_BARRIER); |
| 14039 } | 14012 } |
| 14040 | 14013 |
| 14041 } } // namespace v8::internal | 14014 } } // namespace v8::internal |
| OLD | NEW |