Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(285)

Side by Side Diff: src/objects.cc

Issue 207553005: TransitionElementsKind() and its recursive call chain handlified. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Addressing review notes Created 6 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/objects.h ('k') | src/runtime.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 1514 matching lines...) Expand 10 before | Expand all | Expand 10 after
1525 JSValue::cast(this)->value()->ShortPrint(accumulator); 1525 JSValue::cast(this)->value()->ShortPrint(accumulator);
1526 } 1526 }
1527 accumulator->Put('>'); 1527 accumulator->Put('>');
1528 break; 1528 break;
1529 } 1529 }
1530 } 1530 }
1531 } 1531 }
1532 1532
1533 1533
1534 void JSObject::PrintElementsTransition( 1534 void JSObject::PrintElementsTransition(
1535 FILE* file, ElementsKind from_kind, FixedArrayBase* from_elements, 1535 FILE* file, Handle<JSObject> object,
1536 ElementsKind to_kind, FixedArrayBase* to_elements) { 1536 ElementsKind from_kind, Handle<FixedArrayBase> from_elements,
1537 ElementsKind to_kind, Handle<FixedArrayBase> to_elements) {
1537 if (from_kind != to_kind) { 1538 if (from_kind != to_kind) {
1538 PrintF(file, "elements transition ["); 1539 PrintF(file, "elements transition [");
1539 PrintElementsKind(file, from_kind); 1540 PrintElementsKind(file, from_kind);
1540 PrintF(file, " -> "); 1541 PrintF(file, " -> ");
1541 PrintElementsKind(file, to_kind); 1542 PrintElementsKind(file, to_kind);
1542 PrintF(file, "] in "); 1543 PrintF(file, "] in ");
1543 JavaScriptFrame::PrintTop(GetIsolate(), file, false, true); 1544 JavaScriptFrame::PrintTop(object->GetIsolate(), file, false, true);
1544 PrintF(file, " for "); 1545 PrintF(file, " for ");
1545 ShortPrint(file); 1546 object->ShortPrint(file);
1546 PrintF(file, " from "); 1547 PrintF(file, " from ");
1547 from_elements->ShortPrint(file); 1548 from_elements->ShortPrint(file);
1548 PrintF(file, " to "); 1549 PrintF(file, " to ");
1549 to_elements->ShortPrint(file); 1550 to_elements->ShortPrint(file);
1550 PrintF(file, "\n"); 1551 PrintF(file, "\n");
1551 } 1552 }
1552 } 1553 }
1553 1554
1554 1555
1555 void Map::PrintGeneralization(FILE* file, 1556 void Map::PrintGeneralization(FILE* file,
(...skipping 9576 matching lines...) Expand 10 before | Expand all | Expand 10 after
11132 PrintF(out, "\n"); 11133 PrintF(out, "\n");
11133 } 11134 }
11134 #endif // ENABLE_DISASSEMBLER 11135 #endif // ENABLE_DISASSEMBLER
11135 11136
11136 11137
11137 Handle<FixedArray> JSObject::SetFastElementsCapacityAndLength( 11138 Handle<FixedArray> JSObject::SetFastElementsCapacityAndLength(
11138 Handle<JSObject> object, 11139 Handle<JSObject> object,
11139 int capacity, 11140 int capacity,
11140 int length, 11141 int length,
11141 SetFastElementsCapacitySmiMode smi_mode) { 11142 SetFastElementsCapacitySmiMode smi_mode) {
11142 CALL_HEAP_FUNCTION(
11143 object->GetIsolate(),
11144 object->SetFastElementsCapacityAndLength(capacity, length, smi_mode),
11145 FixedArray);
11146 }
11147
11148
11149 MaybeObject* JSObject::SetFastElementsCapacityAndLength(
11150 int capacity,
11151 int length,
11152 SetFastElementsCapacitySmiMode smi_mode) {
11153 Heap* heap = GetHeap();
11154 // We should never end in here with a pixel or external array. 11143 // We should never end in here with a pixel or external array.
11155 ASSERT(!HasExternalArrayElements()); 11144 ASSERT(!object->HasExternalArrayElements());
11156 11145
11157 // Allocate a new fast elements backing store. 11146 // Allocate a new fast elements backing store.
11158 FixedArray* new_elements; 11147 Handle<FixedArray> new_elements =
11159 MaybeObject* maybe = heap->AllocateUninitializedFixedArray(capacity); 11148 object->GetIsolate()->factory()->NewUninitializedFixedArray(capacity);
11160 if (!maybe->To(&new_elements)) return maybe;
11161 11149
11162 ElementsKind elements_kind = GetElementsKind(); 11150 ElementsKind elements_kind = object->GetElementsKind();
11163 ElementsKind new_elements_kind; 11151 ElementsKind new_elements_kind;
11164 // The resized array has FAST_*_SMI_ELEMENTS if the capacity mode forces it, 11152 // The resized array has FAST_*_SMI_ELEMENTS if the capacity mode forces it,
11165 // or if it's allowed and the old elements array contained only SMIs. 11153 // or if it's allowed and the old elements array contained only SMIs.
11166 bool has_fast_smi_elements = 11154 bool has_fast_smi_elements =
11167 (smi_mode == kForceSmiElements) || 11155 (smi_mode == kForceSmiElements) ||
11168 ((smi_mode == kAllowSmiElements) && HasFastSmiElements()); 11156 ((smi_mode == kAllowSmiElements) && object->HasFastSmiElements());
11169 if (has_fast_smi_elements) { 11157 if (has_fast_smi_elements) {
11170 if (IsHoleyElementsKind(elements_kind)) { 11158 if (IsHoleyElementsKind(elements_kind)) {
11171 new_elements_kind = FAST_HOLEY_SMI_ELEMENTS; 11159 new_elements_kind = FAST_HOLEY_SMI_ELEMENTS;
11172 } else { 11160 } else {
11173 new_elements_kind = FAST_SMI_ELEMENTS; 11161 new_elements_kind = FAST_SMI_ELEMENTS;
11174 } 11162 }
11175 } else { 11163 } else {
11176 if (IsHoleyElementsKind(elements_kind)) { 11164 if (IsHoleyElementsKind(elements_kind)) {
11177 new_elements_kind = FAST_HOLEY_ELEMENTS; 11165 new_elements_kind = FAST_HOLEY_ELEMENTS;
11178 } else { 11166 } else {
11179 new_elements_kind = FAST_ELEMENTS; 11167 new_elements_kind = FAST_ELEMENTS;
11180 } 11168 }
11181 } 11169 }
11182 FixedArrayBase* old_elements = elements(); 11170 Handle<FixedArrayBase> old_elements(object->elements());
11183 ElementsAccessor* accessor = ElementsAccessor::ForKind(new_elements_kind); 11171 ElementsAccessor* accessor = ElementsAccessor::ForKind(new_elements_kind);
11184 MaybeObject* maybe_obj = 11172 accessor->CopyElements(object, new_elements, elements_kind);
11185 accessor->CopyElements(this, new_elements, elements_kind);
11186 if (maybe_obj->IsFailure()) return maybe_obj;
11187 11173
11188 if (elements_kind != SLOPPY_ARGUMENTS_ELEMENTS) { 11174 if (elements_kind != SLOPPY_ARGUMENTS_ELEMENTS) {
11189 Map* new_map = map(); 11175 Handle<Map> new_map = (new_elements_kind != elements_kind)
11190 if (new_elements_kind != elements_kind) { 11176 ? GetElementsTransitionMap(object, new_elements_kind)
11191 MaybeObject* maybe = 11177 : handle(object->map());
11192 GetElementsTransitionMap(GetIsolate(), new_elements_kind); 11178 object->ValidateElements();
11193 if (!maybe->To(&new_map)) return maybe; 11179 object->set_map_and_elements(*new_map, *new_elements);
11194 }
11195 ValidateElements();
11196 set_map_and_elements(new_map, new_elements);
11197 11180
11198 // Transition through the allocation site as well if present. 11181 // Transition through the allocation site as well if present.
11199 maybe_obj = UpdateAllocationSite(new_elements_kind); 11182 JSObject::UpdateAllocationSite(object, new_elements_kind);
11200 if (maybe_obj->IsFailure()) return maybe_obj;
11201 } else { 11183 } else {
11202 FixedArray* parameter_map = FixedArray::cast(old_elements); 11184 Handle<FixedArray> parameter_map = Handle<FixedArray>::cast(old_elements);
11203 parameter_map->set(1, new_elements); 11185 parameter_map->set(1, *new_elements);
11204 } 11186 }
11205 11187
11206 if (FLAG_trace_elements_transitions) { 11188 if (FLAG_trace_elements_transitions) {
11207 PrintElementsTransition(stdout, elements_kind, old_elements, 11189 PrintElementsTransition(stdout, object, elements_kind, old_elements,
11208 GetElementsKind(), new_elements); 11190 object->GetElementsKind(), new_elements);
11209 } 11191 }
11210 11192
11211 if (IsJSArray()) { 11193 if (object->IsJSArray()) {
11212 JSArray::cast(this)->set_length(Smi::FromInt(length)); 11194 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(length));
11213 } 11195 }
11214 return new_elements; 11196 return new_elements;
11215 } 11197 }
11216 11198
11217 11199
11218 void JSObject::SetFastDoubleElementsCapacityAndLength(Handle<JSObject> object, 11200 void JSObject::SetFastDoubleElementsCapacityAndLength(Handle<JSObject> object,
11219 int capacity, 11201 int capacity,
11220 int length) { 11202 int length) {
11221 CALL_HEAP_FUNCTION_VOID( 11203 // We should never end in here with a pixel or external array.
11222 object->GetIsolate(), 11204 ASSERT(!object->HasExternalArrayElements());
11223 object->SetFastDoubleElementsCapacityAndLength(capacity, length));
11224 }
11225 11205
11206 Handle<FixedArrayBase> elems =
11207 object->GetIsolate()->factory()->NewFixedDoubleArray(capacity);
11226 11208
11227 MaybeObject* JSObject::SetFastDoubleElementsCapacityAndLength( 11209 ElementsKind elements_kind = object->GetElementsKind();
11228 int capacity,
11229 int length) {
11230 Heap* heap = GetHeap();
11231 // We should never end in here with a pixel or external array.
11232 ASSERT(!HasExternalArrayElements());
11233
11234 FixedArrayBase* elems;
11235 { MaybeObject* maybe_obj =
11236 heap->AllocateUninitializedFixedDoubleArray(capacity);
11237 if (!maybe_obj->To(&elems)) return maybe_obj;
11238 }
11239
11240 ElementsKind elements_kind = GetElementsKind();
11241 CHECK(elements_kind != SLOPPY_ARGUMENTS_ELEMENTS); 11210 CHECK(elements_kind != SLOPPY_ARGUMENTS_ELEMENTS);
11242 ElementsKind new_elements_kind = elements_kind; 11211 ElementsKind new_elements_kind = elements_kind;
11243 if (IsHoleyElementsKind(elements_kind)) { 11212 if (IsHoleyElementsKind(elements_kind)) {
11244 new_elements_kind = FAST_HOLEY_DOUBLE_ELEMENTS; 11213 new_elements_kind = FAST_HOLEY_DOUBLE_ELEMENTS;
11245 } else { 11214 } else {
11246 new_elements_kind = FAST_DOUBLE_ELEMENTS; 11215 new_elements_kind = FAST_DOUBLE_ELEMENTS;
11247 } 11216 }
11248 11217
11249 Map* new_map; 11218 Handle<Map> new_map = GetElementsTransitionMap(object, new_elements_kind);
11250 { MaybeObject* maybe_obj = 11219
11251 GetElementsTransitionMap(heap->isolate(), new_elements_kind); 11220 Handle<FixedArrayBase> old_elements(object->elements());
11252 if (!maybe_obj->To(&new_map)) return maybe_obj; 11221 ElementsAccessor* accessor = ElementsAccessor::ForKind(FAST_DOUBLE_ELEMENTS);
11222 accessor->CopyElements(object, elems, elements_kind);
11223
11224 object->ValidateElements();
11225 object->set_map_and_elements(*new_map, *elems);
11226
11227 if (FLAG_trace_elements_transitions) {
11228 PrintElementsTransition(stdout, object, elements_kind, old_elements,
11229 object->GetElementsKind(), elems);
11253 } 11230 }
11254 11231
11255 FixedArrayBase* old_elements = elements(); 11232 if (object->IsJSArray()) {
11256 ElementsAccessor* accessor = ElementsAccessor::ForKind(FAST_DOUBLE_ELEMENTS); 11233 Handle<JSArray>::cast(object)->set_length(Smi::FromInt(length));
11257 { MaybeObject* maybe_obj =
11258 accessor->CopyElements(this, elems, elements_kind);
11259 if (maybe_obj->IsFailure()) return maybe_obj;
11260 } 11234 }
11261
11262 ValidateElements();
11263 set_map_and_elements(new_map, elems);
11264
11265 if (FLAG_trace_elements_transitions) {
11266 PrintElementsTransition(stdout, elements_kind, old_elements,
11267 GetElementsKind(), elems);
11268 }
11269
11270 if (IsJSArray()) {
11271 JSArray::cast(this)->set_length(Smi::FromInt(length));
11272 }
11273
11274 return this;
11275 } 11235 }
11276 11236
11277 11237
11278 // static 11238 // static
11279 void JSArray::Initialize(Handle<JSArray> array, int capacity, int length) { 11239 void JSArray::Initialize(Handle<JSArray> array, int capacity, int length) {
11280 ASSERT(capacity >= 0); 11240 ASSERT(capacity >= 0);
11281 array->GetIsolate()->factory()->NewJSArrayStorage( 11241 array->GetIsolate()->factory()->NewJSArrayStorage(
11282 array, length, capacity, INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE); 11242 array, length, capacity, INITIALIZE_ARRAY_ELEMENTS_WITH_HOLE);
11283 } 11243 }
11284 11244
(...skipping 1371 matching lines...) Expand 10 before | Expand all | Expand 10 after
12656 } 12616 }
12657 } 12617 }
12658 } 12618 }
12659 // All possible cases have been handled above. Add a return to avoid the 12619 // All possible cases have been handled above. Add a return to avoid the
12660 // complaints from the compiler. 12620 // complaints from the compiler.
12661 UNREACHABLE(); 12621 UNREACHABLE();
12662 return isolate->factory()->null_value(); 12622 return isolate->factory()->null_value();
12663 } 12623 }
12664 12624
12665 12625
12666 void JSObject::TransitionElementsKind(Handle<JSObject> object,
12667 ElementsKind to_kind) {
12668 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(),
12669 object->TransitionElementsKind(to_kind));
12670 }
12671
12672
12673 const double AllocationSite::kPretenureRatio = 0.85; 12626 const double AllocationSite::kPretenureRatio = 0.85;
12674 12627
12675 12628
12676 void AllocationSite::ResetPretenureDecision() { 12629 void AllocationSite::ResetPretenureDecision() {
12677 set_pretenure_decision(kUndecided); 12630 set_pretenure_decision(kUndecided);
12678 set_memento_found_count(0); 12631 set_memento_found_count(0);
12679 set_memento_create_count(0); 12632 set_memento_create_count(0);
12680 } 12633 }
12681 12634
12682 12635
(...skipping 11 matching lines...) Expand all
12694 AllocationSite* current_site = AllocationSite::cast(current); 12647 AllocationSite* current_site = AllocationSite::cast(current);
12695 if (current_site->nested_site() == this) { 12648 if (current_site->nested_site() == this) {
12696 return true; 12649 return true;
12697 } 12650 }
12698 current = current_site->weak_next(); 12651 current = current_site->weak_next();
12699 } 12652 }
12700 return false; 12653 return false;
12701 } 12654 }
12702 12655
12703 12656
12704 MaybeObject* AllocationSite::DigestTransitionFeedback(ElementsKind to_kind) { 12657 void AllocationSite::DigestTransitionFeedback(Handle<AllocationSite> site,
12705 Isolate* isolate = GetIsolate(); 12658 ElementsKind to_kind) {
12659 Isolate* isolate = site->GetIsolate();
12706 12660
12707 if (SitePointsToLiteral() && transition_info()->IsJSArray()) { 12661 if (site->SitePointsToLiteral() && site->transition_info()->IsJSArray()) {
12708 JSArray* transition_info = JSArray::cast(this->transition_info()); 12662 Handle<JSArray> transition_info =
12663 handle(JSArray::cast(site->transition_info()));
12709 ElementsKind kind = transition_info->GetElementsKind(); 12664 ElementsKind kind = transition_info->GetElementsKind();
12710 // if kind is holey ensure that to_kind is as well. 12665 // if kind is holey ensure that to_kind is as well.
12711 if (IsHoleyElementsKind(kind)) { 12666 if (IsHoleyElementsKind(kind)) {
12712 to_kind = GetHoleyElementsKind(to_kind); 12667 to_kind = GetHoleyElementsKind(to_kind);
12713 } 12668 }
12714 if (IsMoreGeneralElementsKindTransition(kind, to_kind)) { 12669 if (IsMoreGeneralElementsKindTransition(kind, to_kind)) {
12715 // If the array is huge, it's not likely to be defined in a local 12670 // If the array is huge, it's not likely to be defined in a local
12716 // function, so we shouldn't make new instances of it very often. 12671 // function, so we shouldn't make new instances of it very often.
12717 uint32_t length = 0; 12672 uint32_t length = 0;
12718 CHECK(transition_info->length()->ToArrayIndex(&length)); 12673 CHECK(transition_info->length()->ToArrayIndex(&length));
12719 if (length <= kMaximumArrayBytesToPretransition) { 12674 if (length <= kMaximumArrayBytesToPretransition) {
12720 if (FLAG_trace_track_allocation_sites) { 12675 if (FLAG_trace_track_allocation_sites) {
12721 bool is_nested = IsNestedSite(); 12676 bool is_nested = site->IsNestedSite();
12722 PrintF( 12677 PrintF(
12723 "AllocationSite: JSArray %p boilerplate %s updated %s->%s\n", 12678 "AllocationSite: JSArray %p boilerplate %s updated %s->%s\n",
12724 reinterpret_cast<void*>(this), 12679 reinterpret_cast<void*>(*site),
12725 is_nested ? "(nested)" : "", 12680 is_nested ? "(nested)" : "",
12726 ElementsKindToString(kind), 12681 ElementsKindToString(kind),
12727 ElementsKindToString(to_kind)); 12682 ElementsKindToString(to_kind));
12728 } 12683 }
12729 MaybeObject* result = transition_info->TransitionElementsKind(to_kind); 12684 JSObject::TransitionElementsKind(transition_info, to_kind);
12730 if (result->IsFailure()) return result; 12685 site->dependent_code()->DeoptimizeDependentCodeGroup(
12731 dependent_code()->DeoptimizeDependentCodeGroup(
12732 isolate, DependentCode::kAllocationSiteTransitionChangedGroup); 12686 isolate, DependentCode::kAllocationSiteTransitionChangedGroup);
12733 } 12687 }
12734 } 12688 }
12735 } else { 12689 } else {
12736 ElementsKind kind = GetElementsKind(); 12690 ElementsKind kind = site->GetElementsKind();
12737 // if kind is holey ensure that to_kind is as well. 12691 // if kind is holey ensure that to_kind is as well.
12738 if (IsHoleyElementsKind(kind)) { 12692 if (IsHoleyElementsKind(kind)) {
12739 to_kind = GetHoleyElementsKind(to_kind); 12693 to_kind = GetHoleyElementsKind(to_kind);
12740 } 12694 }
12741 if (IsMoreGeneralElementsKindTransition(kind, to_kind)) { 12695 if (IsMoreGeneralElementsKindTransition(kind, to_kind)) {
12742 if (FLAG_trace_track_allocation_sites) { 12696 if (FLAG_trace_track_allocation_sites) {
12743 PrintF("AllocationSite: JSArray %p site updated %s->%s\n", 12697 PrintF("AllocationSite: JSArray %p site updated %s->%s\n",
12744 reinterpret_cast<void*>(this), 12698 reinterpret_cast<void*>(*site),
12745 ElementsKindToString(kind), 12699 ElementsKindToString(kind),
12746 ElementsKindToString(to_kind)); 12700 ElementsKindToString(to_kind));
12747 } 12701 }
12748 SetElementsKind(to_kind); 12702 site->SetElementsKind(to_kind);
12749 dependent_code()->DeoptimizeDependentCodeGroup( 12703 site->dependent_code()->DeoptimizeDependentCodeGroup(
12750 isolate, DependentCode::kAllocationSiteTransitionChangedGroup); 12704 isolate, DependentCode::kAllocationSiteTransitionChangedGroup);
12751 } 12705 }
12752 } 12706 }
12753 return this;
12754 } 12707 }
12755 12708
12756 12709
12757 // static 12710 // static
12758 void AllocationSite::AddDependentCompilationInfo(Handle<AllocationSite> site, 12711 void AllocationSite::AddDependentCompilationInfo(Handle<AllocationSite> site,
12759 Reason reason, 12712 Reason reason,
12760 CompilationInfo* info) { 12713 CompilationInfo* info) {
12761 DependentCode::DependencyGroup group = site->ToDependencyGroup(reason); 12714 DependentCode::DependencyGroup group = site->ToDependencyGroup(reason);
12762 Handle<DependentCode> dep(site->dependent_code()); 12715 Handle<DependentCode> dep(site->dependent_code());
12763 Handle<DependentCode> codes = 12716 Handle<DependentCode> codes =
12764 DependentCode::Insert(dep, group, info->object_wrapper()); 12717 DependentCode::Insert(dep, group, info->object_wrapper());
12765 if (*codes != site->dependent_code()) site->set_dependent_code(*codes); 12718 if (*codes != site->dependent_code()) site->set_dependent_code(*codes);
12766 info->dependencies(group)->Add(Handle<HeapObject>(*site), info->zone()); 12719 info->dependencies(group)->Add(Handle<HeapObject>(*site), info->zone());
12767 } 12720 }
12768 12721
12769 12722
12770 void JSObject::UpdateAllocationSite(Handle<JSObject> object, 12723 void JSObject::UpdateAllocationSite(Handle<JSObject> object,
12771 ElementsKind to_kind) { 12724 ElementsKind to_kind) {
12772 CALL_HEAP_FUNCTION_VOID(object->GetIsolate(), 12725 if (!object->IsJSArray()) return;
12773 object->UpdateAllocationSite(to_kind)); 12726
12727 Heap* heap = object->GetHeap();
12728 if (!heap->InNewSpace(*object)) return;
12729
12730 Handle<AllocationSite> site;
12731 {
12732 DisallowHeapAllocation no_allocation;
12733 // Check if there is potentially a memento behind the object. If
12734 // the last word of the momento is on another page we return
12735 // immediatelly.
12736 Address object_address = object->address();
12737 Address memento_address = object_address + JSArray::kSize;
12738 Address last_memento_word_address = memento_address + kPointerSize;
12739 if (!NewSpacePage::OnSamePage(object_address,
12740 last_memento_word_address)) {
12741 return;
12742 }
12743
12744 // Either object is the last object in the new space, or there is another
12745 // object of at least word size (the header map word) following it, so
12746 // suffices to compare ptr and top here.
12747 Address top = heap->NewSpaceTop();
12748 ASSERT(memento_address == top ||
12749 memento_address + HeapObject::kHeaderSize <= top);
12750 if (memento_address == top) return;
12751
12752 HeapObject* candidate = HeapObject::FromAddress(memento_address);
12753 if (candidate->map() != heap->allocation_memento_map()) return;
12754
12755 AllocationMemento* memento = AllocationMemento::cast(candidate);
12756 if (!memento->IsValid()) return;
12757
12758 // Walk through to the Allocation Site
12759 site = handle(memento->GetAllocationSite());
12760 }
12761 AllocationSite::DigestTransitionFeedback(site, to_kind);
12774 } 12762 }
12775 12763
12776 12764
12777 MaybeObject* JSObject::UpdateAllocationSite(ElementsKind to_kind) { 12765 void JSObject::TransitionElementsKind(Handle<JSObject> object,
12778 if (!IsJSArray()) return this; 12766 ElementsKind to_kind) {
12779 12767 ElementsKind from_kind = object->map()->elements_kind();
12780 Heap* heap = GetHeap();
12781 if (!heap->InNewSpace(this)) return this;
12782
12783 // Check if there is potentially a memento behind the object. If
12784 // the last word of the momento is on another page we return
12785 // immediatelly.
12786 Address object_address = address();
12787 Address memento_address = object_address + JSArray::kSize;
12788 Address last_memento_word_address = memento_address + kPointerSize;
12789 if (!NewSpacePage::OnSamePage(object_address,
12790 last_memento_word_address)) {
12791 return this;
12792 }
12793
12794 // Either object is the last object in the new space, or there is another
12795 // object of at least word size (the header map word) following it, so
12796 // suffices to compare ptr and top here.
12797 Address top = heap->NewSpaceTop();
12798 ASSERT(memento_address == top ||
12799 memento_address + HeapObject::kHeaderSize <= top);
12800 if (memento_address == top) return this;
12801
12802 HeapObject* candidate = HeapObject::FromAddress(memento_address);
12803 if (candidate->map() != heap->allocation_memento_map()) return this;
12804
12805 AllocationMemento* memento = AllocationMemento::cast(candidate);
12806 if (!memento->IsValid()) return this;
12807
12808 // Walk through to the Allocation Site
12809 AllocationSite* site = memento->GetAllocationSite();
12810 return site->DigestTransitionFeedback(to_kind);
12811 }
12812
12813
12814 MaybeObject* JSObject::TransitionElementsKind(ElementsKind to_kind) {
12815 ElementsKind from_kind = map()->elements_kind();
12816 12768
12817 if (IsFastHoleyElementsKind(from_kind)) { 12769 if (IsFastHoleyElementsKind(from_kind)) {
12818 to_kind = GetHoleyElementsKind(to_kind); 12770 to_kind = GetHoleyElementsKind(to_kind);
12819 } 12771 }
12820 12772
12821 if (from_kind == to_kind) return this; 12773 if (from_kind == to_kind) return;
12822 // Don't update the site if to_kind isn't fast 12774 // Don't update the site if to_kind isn't fast
12823 if (IsFastElementsKind(to_kind)) { 12775 if (IsFastElementsKind(to_kind)) {
12824 MaybeObject* maybe_failure = UpdateAllocationSite(to_kind); 12776 UpdateAllocationSite(object, to_kind);
12825 if (maybe_failure->IsFailure()) return maybe_failure;
12826 } 12777 }
12827 12778
12828 Isolate* isolate = GetIsolate(); 12779 Isolate* isolate = object->GetIsolate();
12829 if (elements() == isolate->heap()->empty_fixed_array() || 12780 if (object->elements() == isolate->heap()->empty_fixed_array() ||
12830 (IsFastSmiOrObjectElementsKind(from_kind) && 12781 (IsFastSmiOrObjectElementsKind(from_kind) &&
12831 IsFastSmiOrObjectElementsKind(to_kind)) || 12782 IsFastSmiOrObjectElementsKind(to_kind)) ||
12832 (from_kind == FAST_DOUBLE_ELEMENTS && 12783 (from_kind == FAST_DOUBLE_ELEMENTS &&
12833 to_kind == FAST_HOLEY_DOUBLE_ELEMENTS)) { 12784 to_kind == FAST_HOLEY_DOUBLE_ELEMENTS)) {
12834 ASSERT(from_kind != TERMINAL_FAST_ELEMENTS_KIND); 12785 ASSERT(from_kind != TERMINAL_FAST_ELEMENTS_KIND);
12835 // No change is needed to the elements() buffer, the transition 12786 // No change is needed to the elements() buffer, the transition
12836 // only requires a map change. 12787 // only requires a map change.
12837 MaybeObject* maybe_new_map = GetElementsTransitionMap(isolate, to_kind); 12788 Handle<Map> new_map = GetElementsTransitionMap(object, to_kind);
12838 Map* new_map; 12789 MigrateToMap(object, new_map);
12839 if (!maybe_new_map->To(&new_map)) return maybe_new_map;
12840 // TODO(verwaest): Replace by MigrateToMap.
12841 set_map(new_map);
12842 if (FLAG_trace_elements_transitions) { 12790 if (FLAG_trace_elements_transitions) {
12843 FixedArrayBase* elms = FixedArrayBase::cast(elements()); 12791 Handle<FixedArrayBase> elms(object->elements());
12844 PrintElementsTransition(stdout, from_kind, elms, to_kind, elms); 12792 PrintElementsTransition(stdout, object, from_kind, elms, to_kind, elms);
12845 } 12793 }
12846 return this; 12794 return;
12847 } 12795 }
12848 12796
12849 FixedArrayBase* elms = FixedArrayBase::cast(elements()); 12797 Handle<FixedArrayBase> elms(object->elements());
12850 uint32_t capacity = static_cast<uint32_t>(elms->length()); 12798 uint32_t capacity = static_cast<uint32_t>(elms->length());
12851 uint32_t length = capacity; 12799 uint32_t length = capacity;
12852 12800
12853 if (IsJSArray()) { 12801 if (object->IsJSArray()) {
12854 Object* raw_length = JSArray::cast(this)->length(); 12802 Object* raw_length = Handle<JSArray>::cast(object)->length();
12855 if (raw_length->IsUndefined()) { 12803 if (raw_length->IsUndefined()) {
12856 // If length is undefined, then JSArray is being initialized and has no 12804 // If length is undefined, then JSArray is being initialized and has no
12857 // elements, assume a length of zero. 12805 // elements, assume a length of zero.
12858 length = 0; 12806 length = 0;
12859 } else { 12807 } else {
12860 CHECK(JSArray::cast(this)->length()->ToArrayIndex(&length)); 12808 CHECK(raw_length->ToArrayIndex(&length));
12861 } 12809 }
12862 } 12810 }
12863 12811
12864 if (IsFastSmiElementsKind(from_kind) && 12812 if (IsFastSmiElementsKind(from_kind) &&
12865 IsFastDoubleElementsKind(to_kind)) { 12813 IsFastDoubleElementsKind(to_kind)) {
12866 MaybeObject* maybe_result = 12814 SetFastDoubleElementsCapacityAndLength(object, capacity, length);
12867 SetFastDoubleElementsCapacityAndLength(capacity, length); 12815 object->ValidateElements();
12868 if (maybe_result->IsFailure()) return maybe_result; 12816 return;
12869 ValidateElements();
12870 return this;
12871 } 12817 }
12872 12818
12873 if (IsFastDoubleElementsKind(from_kind) && 12819 if (IsFastDoubleElementsKind(from_kind) &&
12874 IsFastObjectElementsKind(to_kind)) { 12820 IsFastObjectElementsKind(to_kind)) {
12875 MaybeObject* maybe_result = SetFastElementsCapacityAndLength( 12821 SetFastElementsCapacityAndLength(object, capacity, length,
12876 capacity, length, kDontAllowSmiElements); 12822 kDontAllowSmiElements);
12877 if (maybe_result->IsFailure()) return maybe_result; 12823 object->ValidateElements();
12878 ValidateElements(); 12824 return;
12879 return this;
12880 } 12825 }
12881 12826
12882 // This method should never be called for any other case than the ones 12827 // This method should never be called for any other case than the ones
12883 // handled above. 12828 // handled above.
12884 UNREACHABLE(); 12829 UNREACHABLE();
12885 return GetIsolate()->heap()->null_value();
12886 } 12830 }
12887 12831
12888 12832
12889 // static 12833 // static
12890 bool Map::IsValidElementsTransition(ElementsKind from_kind, 12834 bool Map::IsValidElementsTransition(ElementsKind from_kind,
12891 ElementsKind to_kind) { 12835 ElementsKind to_kind) {
12892 // Transitions can't go backwards. 12836 // Transitions can't go backwards.
12893 if (!IsMoreGeneralElementsKindTransition(from_kind, to_kind)) { 12837 if (!IsMoreGeneralElementsKindTransition(from_kind, to_kind)) {
12894 return false; 12838 return false;
12895 } 12839 }
(...skipping 3523 matching lines...) Expand 10 before | Expand all | Expand 10 after
16419 #define ERROR_MESSAGES_TEXTS(C, T) T, 16363 #define ERROR_MESSAGES_TEXTS(C, T) T,
16420 static const char* error_messages_[] = { 16364 static const char* error_messages_[] = {
16421 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS) 16365 ERROR_MESSAGES_LIST(ERROR_MESSAGES_TEXTS)
16422 }; 16366 };
16423 #undef ERROR_MESSAGES_TEXTS 16367 #undef ERROR_MESSAGES_TEXTS
16424 return error_messages_[reason]; 16368 return error_messages_[reason];
16425 } 16369 }
16426 16370
16427 16371
16428 } } // namespace v8::internal 16372 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/objects.h ('k') | src/runtime.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698