Index: src/runtime.cc |
diff --git a/src/runtime.cc b/src/runtime.cc |
index 14123891406ab940c42cbbc53693fb0a75028b60..fdbd5afb1bf08da92f7de15b65c046e0a8bb1f4e 100644 |
--- a/src/runtime.cc |
+++ b/src/runtime.cc |
@@ -40,6 +40,7 @@ |
#include "debug.h" |
#include "deoptimizer.h" |
#include "execution.h" |
+#include "global-handles.h" |
#include "jsregexp.h" |
#include "liveedit.h" |
#include "parser.h" |
@@ -8041,10 +8042,14 @@ class ArrayConcatVisitor { |
public: |
ArrayConcatVisitor(Handle<FixedArray> storage, |
bool fast_elements) : |
- storage_(storage), |
+ storage_(Handle<FixedArray>::cast(GlobalHandles::Create(*storage))), |
index_offset_(0u), |
fast_elements_(fast_elements) { } |
+ ~ArrayConcatVisitor() { |
+ clear_storage(); |
+ } |
+ |
void visit(uint32_t i, Handle<Object> elm) { |
if (i >= JSObject::kMaxElementCount - index_offset_) return; |
uint32_t index = index_offset_ + i; |
@@ -8062,11 +8067,13 @@ class ArrayConcatVisitor { |
// Fall-through to dictionary mode. |
} |
ASSERT(!fast_elements_); |
- Handle<NumberDictionary> dict(storage_.cast<NumberDictionary>()); |
+ Handle<NumberDictionary> dict(NumberDictionary::cast(*storage_)); |
Handle<NumberDictionary> result = |
Factory::DictionaryAtNumberPut(dict, index, elm); |
if (!result.is_identical_to(dict)) { |
- storage_ = Handle<FixedArray>::cast(result); |
+ // Dictionary needed to grow. |
+ clear_storage(); |
+ set_storage(*result); |
} |
} |
@@ -8098,23 +8105,35 @@ class ArrayConcatVisitor { |
// Convert storage to dictionary mode. |
void SetDictionaryMode(uint32_t index) { |
ASSERT(fast_elements_); |
- Handle<FixedArray> current_storage(storage_.ToHandle()); |
- HandleCell<NumberDictionary> slow_storage( |
+ Handle<FixedArray> current_storage(*storage_); |
+ Handle<NumberDictionary> slow_storage( |
Factory::NewNumberDictionary(current_storage->length())); |
uint32_t current_length = static_cast<uint32_t>(current_storage->length()); |
for (uint32_t i = 0; i < current_length; i++) { |
HandleScope loop_scope; |
Handle<Object> element(current_storage->get(i)); |
if (!element->IsTheHole()) { |
- slow_storage = |
- Factory::DictionaryAtNumberPut(slow_storage.ToHandle(), i, element); |
+ Handle<NumberDictionary> new_storage = |
+ Factory::DictionaryAtNumberPut(slow_storage, i, element); |
+ if (!new_storage.is_identical_to(slow_storage)) { |
+ slow_storage = loop_scope.CloseAndEscape(new_storage); |
+ } |
} |
} |
- storage_ = slow_storage.cast<FixedArray>(); |
+ clear_storage(); |
+ set_storage(*slow_storage); |
fast_elements_ = false; |
} |
- HandleCell<FixedArray> storage_; |
+ inline void clear_storage() { |
+ GlobalHandles::Destroy(Handle<Object>::cast(storage_).location()); |
+ } |
+ |
+ inline void set_storage(FixedArray* storage) { |
+ storage_ = Handle<FixedArray>::cast(GlobalHandles::Create(storage)); |
+ } |
+ |
+ Handle<FixedArray> storage_; // Always a global handle. |
// Index after last seen index. Always less than or equal to |
// JSObject::kMaxElementCount. |
uint32_t index_offset_; |