Index: src/objects.cc |
diff --git a/src/objects.cc b/src/objects.cc |
index a65a3174fb5a4d2f6607a54a5a0e15bcf092daa3..009cd5453d4825ba1a0cc422b1a073fdb1cbfa42 100644 |
--- a/src/objects.cc |
+++ b/src/objects.cc |
@@ -1,4 +1,4 @@ |
-// Copyright 2012 the V8 project authors. All rights reserved. |
+// Copyright 2013 the V8 project authors. All rights reserved. |
// Redistribution and use in source and binary forms, with or without |
// modification, are permitted provided that the following conditions are |
// met: |
@@ -7512,6 +7512,21 @@ AllocationSiteInfo* AllocationSiteInfo::FindForJSObject(JSObject* object) { |
} |
+bool AllocationSiteInfo::GetElementsKindPayload(ElementsKind* kind) { |
+ ASSERT(kind != NULL); |
+ if (payload()->IsJSGlobalPropertyCell()) { |
+ JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(payload()); |
+ Object* cell_contents = cell->value(); |
+ if (cell_contents->IsSmi()) { |
+ *kind = static_cast<ElementsKind>( |
+ Smi::cast(cell_contents)->value()); |
+ return true; |
+ } |
+ } |
+ return false; |
+} |
+ |
+ |
// Heuristic: We only need to create allocation site info if the boilerplate |
// elements kind is the initial elements kind. |
AllocationSiteMode AllocationSiteInfo::GetMode( |
@@ -9336,11 +9351,17 @@ MaybeObject* JSArray::Initialize(int capacity) { |
Heap* heap = GetHeap(); |
ASSERT(capacity >= 0); |
set_length(Smi::FromInt(0)); |
- FixedArray* new_elements; |
+ FixedArrayBase* new_elements; |
if (capacity == 0) { |
new_elements = heap->empty_fixed_array(); |
} else { |
- MaybeObject* maybe_obj = heap->AllocateFixedArrayWithHoles(capacity); |
+ ElementsKind elements_kind = GetElementsKind(); |
+ MaybeObject* maybe_obj; |
+ if (IsFastDoubleElementsKind(elements_kind)) { |
+ maybe_obj = heap->AllocateFixedDoubleArrayWithHoles(capacity); |
+ } else { |
+ maybe_obj = heap->AllocateFixedArrayWithHoles(capacity); |
+ } |
Toon Verwaest
2013/02/13 15:14:51
Seems like this is overlapping with AllocateJSArra
mvstanton
2013/02/19 11:04:08
Done.
|
if (!maybe_obj->To(&new_elements)) return maybe_obj; |
} |
set_elements(new_elements); |
@@ -10530,6 +10551,12 @@ Handle<Object> JSObject::TransitionElementsKind(Handle<JSObject> object, |
} |
+// TODO(mvstanton): rename this method to reflect what it actually does. |
+// If a boilerplate object is discovered, then it will transition it. |
+// If instead there is a elements kind, then update it as long as the |
+// to_kind variable is more general than what we find, but don't |
+// ever take the double->fastobject transition (that represents poisoning), |
+// just ignore that case. |
MaybeObject* JSObject::PossiblyTransitionArrayBoilerplate( |
ElementsKind to_kind) { |
MaybeObject* ret = NULL; |
Toon Verwaest
2013/02/13 15:14:51
Seems like you don't need this variable. Below you
mvstanton
2013/02/19 11:04:08
Done. And I addressed my TODO above, renaming the
|
@@ -10542,22 +10569,43 @@ MaybeObject* JSObject::PossiblyTransitionArrayBoilerplate( |
return ret; |
} |
- ASSERT(info->payload()->IsJSArray()); |
- JSArray* payload = JSArray::cast(info->payload()); |
- ElementsKind kind = payload->GetElementsKind(); |
- if (IsMoreGeneralElementsKindTransition(kind, to_kind)) { |
- // If the array is huge, it's not likely to be defined in a local |
- // function, so we shouldn't make new instances of it very often. |
- uint32_t length = 0; |
- CHECK(payload->length()->ToArrayIndex(&length)); |
- if (length <= 8 * 1024) { |
- ret = payload->TransitionElementsKind(to_kind); |
- if (FLAG_trace_track_allocation_sites) { |
- PrintF( |
- "AllocationSiteInfo: JSArray %p boilerplate updated %s->%s\n", |
- reinterpret_cast<void*>(this), |
- ElementsKindToString(kind), |
- ElementsKindToString(to_kind)); |
+ if (info->payload()->IsJSArray()) { |
+ JSArray* payload = JSArray::cast(info->payload()); |
+ ElementsKind kind = payload->GetElementsKind(); |
+ if (IsMoreGeneralElementsKindTransition(kind, to_kind)) { |
+ // If the array is huge, it's not likely to be defined in a local |
+ // function, so we shouldn't make new instances of it very often. |
+ uint32_t length = 0; |
+ CHECK(payload->length()->ToArrayIndex(&length)); |
+ if (length <= 8*1024) { |
Toon Verwaest
2013/02/13 15:14:51
Define a constant.
mvstanton
2013/02/19 11:04:08
Done.
|
+ ret = payload->TransitionElementsKind(to_kind); |
+ if (FLAG_trace_track_allocation_sites) { |
+ PrintF( |
+ "AllocationSiteInfo: JSArray %p boilerplate updated %s->%s\n", |
+ reinterpret_cast<void*>(this), |
+ ElementsKindToString(kind), |
+ ElementsKindToString(to_kind)); |
+ } |
+ } |
+ } |
+ } else if (info->payload()->IsJSGlobalPropertyCell()) { |
+ JSGlobalPropertyCell* cell = JSGlobalPropertyCell::cast(info->payload()); |
+ Object* cell_contents = cell->value(); |
+ if (cell_contents->IsSmi()) { |
+ ElementsKind kind = static_cast<ElementsKind>( |
+ Smi::cast(cell_contents)->value()); |
+ // Specifically exclude DOUBLE(HOLEY) -> FAST(HOLEY) |
+ bool double_to_fast = IsFastDoubleElementsKind(kind) && |
+ IsFastObjectElementsKind(to_kind); |
Toon Verwaest
2013/02/13 15:14:51
This heuristic seems very buried away. Can we make
mvstanton
2013/02/19 11:04:08
Yep, I just didn't revisit this code in a while, t
mvstanton
2013/02/19 11:04:08
Done.
|
+ if (IsMoreGeneralElementsKindTransition(kind, to_kind) && |
+ !double_to_fast) { |
+ if (FLAG_trace_track_allocation_sites) { |
+ PrintF("AllocationSiteInfo: JSArray %p info updated %s->%s\n", |
+ reinterpret_cast<void*>(this), |
+ ElementsKindToString(kind), |
+ ElementsKindToString(to_kind)); |
+ } |
+ cell->set_value(Smi::FromInt(to_kind)); |
} |
} |
} |