summaryrefslogtreecommitdiff
path: root/deps/v8/src/transitions.cc
diff options
context:
space:
mode:
Diffstat (limited to 'deps/v8/src/transitions.cc')
-rw-r--r--deps/v8/src/transitions.cc156
1 files changed, 78 insertions, 78 deletions
diff --git a/deps/v8/src/transitions.cc b/deps/v8/src/transitions.cc
index 9d3f038947..7fd56cbe23 100644
--- a/deps/v8/src/transitions.cc
+++ b/deps/v8/src/transitions.cc
@@ -1,29 +1,6 @@
// Copyright 2012 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:
-//
-// * Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-// * Redistributions in binary form must reproduce the above
-// copyright notice, this list of conditions and the following
-// disclaimer in the documentation and/or other materials provided
-// with the distribution.
-// * Neither the name of Google Inc. nor the names of its
-// contributors may be used to endorse or promote products derived
-// from this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
#include "v8.h"
@@ -35,23 +12,21 @@ namespace v8 {
namespace internal {
-static MaybeObject* AllocateRaw(Isolate* isolate, int length) {
- // Use FixedArray to not use TransitionArray::cast on incomplete object.
- FixedArray* array;
- MaybeObject* maybe_array = isolate->heap()->AllocateFixedArray(length);
- if (!maybe_array->To(&array)) return maybe_array;
- return array;
+Handle<TransitionArray> TransitionArray::Allocate(Isolate* isolate,
+ int number_of_transitions) {
+ Handle<FixedArray> array =
+ isolate->factory()->NewFixedArray(ToKeyIndex(number_of_transitions));
+ array->set(kPrototypeTransitionsIndex, Smi::FromInt(0));
+ return Handle<TransitionArray>::cast(array);
}
-MaybeObject* TransitionArray::Allocate(Isolate* isolate,
- int number_of_transitions) {
- FixedArray* array;
- MaybeObject* maybe_array =
- AllocateRaw(isolate, ToKeyIndex(number_of_transitions));
- if (!maybe_array->To(&array)) return maybe_array;
- array->set(kPrototypeTransitionsIndex, Smi::FromInt(0));
- return array;
+Handle<TransitionArray> TransitionArray::AllocateSimple(Isolate* isolate,
+ Handle<Map> target) {
+ Handle<FixedArray> array =
+ isolate->factory()->NewFixedArray(kSimpleTransitionSize);
+ array->set(kSimpleTransitionTarget, *target);
+ return Handle<TransitionArray>::cast(array);
}
@@ -69,86 +44,111 @@ static bool InsertionPointFound(Name* key1, Name* key2) {
}
-MaybeObject* TransitionArray::NewWith(SimpleTransitionFlag flag,
- Name* key,
- Map* target,
- Object* back_pointer) {
- TransitionArray* result;
- MaybeObject* maybe_result;
+Handle<TransitionArray> TransitionArray::NewWith(Handle<Map> map,
+ Handle<Name> name,
+ Handle<Map> target,
+ SimpleTransitionFlag flag) {
+ Handle<TransitionArray> result;
+ Isolate* isolate = name->GetIsolate();
if (flag == SIMPLE_TRANSITION) {
- maybe_result = AllocateRaw(target->GetIsolate(), kSimpleTransitionSize);
- if (!maybe_result->To(&result)) return maybe_result;
- result->set(kSimpleTransitionTarget, target);
+ result = AllocateSimple(isolate, target);
} else {
- maybe_result = Allocate(target->GetIsolate(), 1);
- if (!maybe_result->To(&result)) return maybe_result;
- result->NoIncrementalWriteBarrierSet(0, key, target);
+ result = Allocate(isolate, 1);
+ result->NoIncrementalWriteBarrierSet(0, *name, *target);
}
- result->set_back_pointer_storage(back_pointer);
+ result->set_back_pointer_storage(map->GetBackPointer());
return result;
}
-MaybeObject* TransitionArray::ExtendToFullTransitionArray() {
- ASSERT(!IsFullTransitionArray());
- int nof = number_of_transitions();
- TransitionArray* result;
- MaybeObject* maybe_result = Allocate(GetIsolate(), nof);
- if (!maybe_result->To(&result)) return maybe_result;
+Handle<TransitionArray> TransitionArray::ExtendToFullTransitionArray(
+ Handle<Map> containing_map) {
+ ASSERT(!containing_map->transitions()->IsFullTransitionArray());
+ int nof = containing_map->transitions()->number_of_transitions();
- if (nof == 1) {
- result->NoIncrementalWriteBarrierCopyFrom(this, kSimpleTransitionIndex, 0);
+ // A transition array may shrink during GC.
+ Handle<TransitionArray> result = Allocate(containing_map->GetIsolate(), nof);
+ DisallowHeapAllocation no_gc;
+ int new_nof = containing_map->transitions()->number_of_transitions();
+ if (new_nof != nof) {
+ ASSERT(new_nof == 0);
+ result->Shrink(ToKeyIndex(0));
+ } else if (nof == 1) {
+ result->NoIncrementalWriteBarrierCopyFrom(
+ containing_map->transitions(), kSimpleTransitionIndex, 0);
}
- result->set_back_pointer_storage(back_pointer_storage());
+ result->set_back_pointer_storage(
+ containing_map->transitions()->back_pointer_storage());
return result;
}
-MaybeObject* TransitionArray::CopyInsert(Name* name, Map* target) {
- TransitionArray* result;
+Handle<TransitionArray> TransitionArray::CopyInsert(Handle<Map> map,
+ Handle<Name> name,
+ Handle<Map> target,
+ SimpleTransitionFlag flag) {
+ if (!map->HasTransitionArray()) {
+ return TransitionArray::NewWith(map, name, target, flag);
+ }
- int number_of_transitions = this->number_of_transitions();
+ int number_of_transitions = map->transitions()->number_of_transitions();
int new_size = number_of_transitions;
- int insertion_index = this->Search(name);
+ int insertion_index = map->transitions()->Search(*name);
if (insertion_index == kNotFound) ++new_size;
- MaybeObject* maybe_array;
- maybe_array = TransitionArray::Allocate(GetIsolate(), new_size);
- if (!maybe_array->To(&result)) return maybe_array;
+ Handle<TransitionArray> result = Allocate(map->GetIsolate(), new_size);
+
+ // The map's transition array may grown smaller during the allocation above as
+ // it was weakly traversed, though it is guaranteed not to disappear. Trim the
+ // result copy if needed, and recompute variables.
+ ASSERT(map->HasTransitionArray());
+ DisallowHeapAllocation no_gc;
+ TransitionArray* array = map->transitions();
+ if (array->number_of_transitions() != number_of_transitions) {
+ ASSERT(array->number_of_transitions() < number_of_transitions);
+
+ number_of_transitions = array->number_of_transitions();
+ new_size = number_of_transitions;
+
+ insertion_index = array->Search(*name);
+ if (insertion_index == kNotFound) ++new_size;
+
+ result->Shrink(ToKeyIndex(new_size));
+ }
- if (HasPrototypeTransitions()) {
- result->SetPrototypeTransitions(GetPrototypeTransitions());
+ if (array->HasPrototypeTransitions()) {
+ result->SetPrototypeTransitions(array->GetPrototypeTransitions());
}
if (insertion_index != kNotFound) {
for (int i = 0; i < number_of_transitions; ++i) {
if (i != insertion_index) {
- result->NoIncrementalWriteBarrierCopyFrom(this, i, i);
+ result->NoIncrementalWriteBarrierCopyFrom(array, i, i);
}
}
- result->NoIncrementalWriteBarrierSet(insertion_index, name, target);
- result->set_back_pointer_storage(back_pointer_storage());
+ result->NoIncrementalWriteBarrierSet(insertion_index, *name, *target);
+ result->set_back_pointer_storage(array->back_pointer_storage());
return result;
}
insertion_index = 0;
for (; insertion_index < number_of_transitions; ++insertion_index) {
- if (InsertionPointFound(GetKey(insertion_index), name)) break;
+ if (InsertionPointFound(array->GetKey(insertion_index), *name)) break;
result->NoIncrementalWriteBarrierCopyFrom(
- this, insertion_index, insertion_index);
+ array, insertion_index, insertion_index);
}
- result->NoIncrementalWriteBarrierSet(insertion_index, name, target);
+ result->NoIncrementalWriteBarrierSet(insertion_index, *name, *target);
for (; insertion_index < number_of_transitions; ++insertion_index) {
result->NoIncrementalWriteBarrierCopyFrom(
- this, insertion_index, insertion_index + 1);
+ array, insertion_index, insertion_index + 1);
}
- result->set_back_pointer_storage(back_pointer_storage());
+ result->set_back_pointer_storage(array->back_pointer_storage());
return result;
}