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

Side by Side Diff: src/objects.cc

Issue 11818021: Allocation Info Tracking, continued. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Review feedback Created 7 years, 10 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
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 9332 matching lines...) Expand 10 before | Expand all | Expand 10 after
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
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
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
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
OLDNEW
« src/heap.cc ('K') | « src/objects.h ('k') | src/x64/code-stubs-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698