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

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

Powered by Google App Engine
This is Rietveld 408576698