summaryrefslogtreecommitdiff
path: root/deps/v8/src/transitions.cc
diff options
context:
space:
mode:
authorAli Ijaz Sheikh <ofrobots@google.com>2016-03-01 08:58:05 -0800
committerAli Sheikh <ofrobots@lemonhope.roam.corp.google.com>2016-03-03 20:35:20 -0800
commit069e02ab47656b3efd1b6829c65856b2e1c2d1db (patch)
treeeb643e0a2e88fd64bb9fc927423458d2ae96c2db /deps/v8/src/transitions.cc
parent8938355398c79f583a468284b768652d12ba9bc9 (diff)
downloadandroid-node-v8-069e02ab47656b3efd1b6829c65856b2e1c2d1db.tar.gz
android-node-v8-069e02ab47656b3efd1b6829c65856b2e1c2d1db.tar.bz2
android-node-v8-069e02ab47656b3efd1b6829c65856b2e1c2d1db.zip
deps: upgrade to V8 4.9.385.18
Pick up the current branch head for V8 4.9 https://github.com/v8/v8/commit/1ecba0f PR-URL: https://github.com/nodejs/node/pull/4722 Reviewed-By: Ben Noordhuis <info@bnoordhuis.nl> Reviewed-By: Michaƫl Zasso <mic.besace@gmail.com>
Diffstat (limited to 'deps/v8/src/transitions.cc')
-rw-r--r--deps/v8/src/transitions.cc131
1 files changed, 80 insertions, 51 deletions
diff --git a/deps/v8/src/transitions.cc b/deps/v8/src/transitions.cc
index 64b8133528..fc24b28867 100644
--- a/deps/v8/src/transitions.cc
+++ b/deps/v8/src/transitions.cc
@@ -51,8 +51,7 @@ void TransitionArray::Insert(Handle<Map> map, Handle<Name> name,
// Re-read existing data; the allocation might have caused it to be cleared.
if (IsSimpleTransition(map->raw_transitions())) {
old_target = GetSimpleTransition(map->raw_transitions());
- result->NoIncrementalWriteBarrierSet(
- 0, GetSimpleTransitionKey(old_target), old_target);
+ result->Set(0, GetSimpleTransitionKey(old_target), old_target);
} else {
result->SetNumberOfTransitions(0);
}
@@ -145,11 +144,11 @@ void TransitionArray::Insert(Handle<Map> map, Handle<Name> name,
DCHECK_NE(kNotFound, insertion_index);
for (int i = 0; i < insertion_index; ++i) {
- result->NoIncrementalWriteBarrierCopyFrom(array, i, i);
+ result->Set(i, array->GetKey(i), array->GetTarget(i));
}
- result->NoIncrementalWriteBarrierSet(insertion_index, *name, *target);
+ result->Set(insertion_index, *name, *target);
for (int i = insertion_index; i < number_of_transitions; ++i) {
- result->NoIncrementalWriteBarrierCopyFrom(array, i, i + 1);
+ result->Set(i + 1, array->GetKey(i), array->GetTarget(i));
}
SLOW_DCHECK(result->IsSortedNoDuplicates());
@@ -234,6 +233,61 @@ bool TransitionArray::CanHaveMoreTransitions(Handle<Map> map) {
// static
+bool TransitionArray::CompactPrototypeTransitionArray(FixedArray* array) {
+ const int header = kProtoTransitionHeaderSize;
+ int number_of_transitions = NumberOfPrototypeTransitions(array);
+ if (number_of_transitions == 0) {
+ // Empty array cannot be compacted.
+ return false;
+ }
+ int new_number_of_transitions = 0;
+ for (int i = 0; i < number_of_transitions; i++) {
+ Object* cell = array->get(header + i);
+ if (!WeakCell::cast(cell)->cleared()) {
+ if (new_number_of_transitions != i) {
+ array->set(header + new_number_of_transitions, cell);
+ }
+ new_number_of_transitions++;
+ }
+ }
+ // Fill slots that became free with undefined value.
+ for (int i = new_number_of_transitions; i < number_of_transitions; i++) {
+ array->set_undefined(header + i);
+ }
+ if (number_of_transitions != new_number_of_transitions) {
+ SetNumberOfPrototypeTransitions(array, new_number_of_transitions);
+ }
+ return new_number_of_transitions < number_of_transitions;
+}
+
+
+// static
+Handle<FixedArray> TransitionArray::GrowPrototypeTransitionArray(
+ Handle<FixedArray> array, int new_capacity, Isolate* isolate) {
+ // Grow array by factor 2 up to MaxCachedPrototypeTransitions.
+ int capacity = array->length() - kProtoTransitionHeaderSize;
+ new_capacity = Min(kMaxCachedPrototypeTransitions, new_capacity);
+ DCHECK_GT(new_capacity, capacity);
+ int grow_by = new_capacity - capacity;
+ array = isolate->factory()->CopyFixedArrayAndGrow(array, grow_by, TENURED);
+ if (capacity < 0) {
+ // There was no prototype transitions array before, so the size
+ // couldn't be copied. Initialize it explicitly.
+ SetNumberOfPrototypeTransitions(*array, 0);
+ }
+ return array;
+}
+
+
+// static
+int TransitionArray::NumberOfPrototypeTransitionsForTest(Map* map) {
+ FixedArray* transitions = GetPrototypeTransitions(map);
+ CompactPrototypeTransitionArray(transitions);
+ return TransitionArray::NumberOfPrototypeTransitions(transitions);
+}
+
+
+// static
void TransitionArray::PutPrototypeTransition(Handle<Map> map,
Handle<Object> prototype,
Handle<Map> target_map) {
@@ -252,23 +306,16 @@ void TransitionArray::PutPrototypeTransition(Handle<Map> map,
int transitions = NumberOfPrototypeTransitions(*cache) + 1;
if (transitions > capacity) {
- // Grow array by factor 2 up to MaxCachedPrototypeTransitions.
- int new_capacity = Min(kMaxCachedPrototypeTransitions, transitions * 2);
- if (new_capacity == capacity) return;
- int grow_by = new_capacity - capacity;
-
- Isolate* isolate = map->GetIsolate();
- cache = isolate->factory()->CopyFixedArrayAndGrow(cache, grow_by);
- if (capacity < 0) {
- // There was no prototype transitions array before, so the size
- // couldn't be copied. Initialize it explicitly.
- SetNumberOfPrototypeTransitions(*cache, 0);
+ // Grow the array if compacting it doesn't free space.
+ if (!CompactPrototypeTransitionArray(*cache)) {
+ if (capacity == kMaxCachedPrototypeTransitions) return;
+ cache = GrowPrototypeTransitionArray(cache, 2 * transitions,
+ map->GetIsolate());
+ SetPrototypeTransitions(map, cache);
}
-
- SetPrototypeTransitions(map, cache);
}
- // Reload number of transitions as GC might shrink them.
+ // Reload number of transitions as they might have been compacted.
int last = NumberOfPrototypeTransitions(*cache);
int entry = header + last;
@@ -344,27 +391,23 @@ int TransitionArray::Capacity(Object* raw_transitions) {
Handle<TransitionArray> TransitionArray::Allocate(Isolate* isolate,
int number_of_transitions,
int slack) {
- Handle<FixedArray> array = isolate->factory()->NewFixedArray(
+ Handle<FixedArray> array = isolate->factory()->NewTransitionArray(
LengthFor(number_of_transitions + slack));
+ array->set(kNextLinkIndex, isolate->heap()->undefined_value());
array->set(kPrototypeTransitionsIndex, Smi::FromInt(0));
array->set(kTransitionLengthIndex, Smi::FromInt(number_of_transitions));
return Handle<TransitionArray>::cast(array);
}
-void TransitionArray::NoIncrementalWriteBarrierCopyFrom(TransitionArray* origin,
- int origin_transition,
- int target_transition) {
- NoIncrementalWriteBarrierSet(target_transition,
- origin->GetKey(origin_transition),
- origin->GetTarget(origin_transition));
-}
-
-
-static void ZapTransitionArray(TransitionArray* transitions) {
- MemsetPointer(transitions->data_start(),
+// static
+void TransitionArray::ZapTransitionArray(TransitionArray* transitions) {
+ // Do not zap the next link that is used by GC.
+ STATIC_ASSERT(kNextLinkIndex + 1 == kPrototypeTransitionsIndex);
+ MemsetPointer(transitions->data_start() + kPrototypeTransitionsIndex,
transitions->GetHeap()->the_hole_value(),
- transitions->length());
+ transitions->length() - kPrototypeTransitionsIndex);
+ transitions->SetNumberOfTransitions(0);
}
@@ -387,25 +430,9 @@ void TransitionArray::ReplaceTransitions(Handle<Map> map,
}
-static void ZapPrototypeTransitions(Object* raw_transitions) {
- DCHECK(TransitionArray::IsFullTransitionArray(raw_transitions));
- TransitionArray* transitions = TransitionArray::cast(raw_transitions);
- if (!transitions->HasPrototypeTransitions()) return;
- FixedArray* proto_transitions = transitions->GetPrototypeTransitions();
- MemsetPointer(proto_transitions->data_start(),
- proto_transitions->GetHeap()->the_hole_value(),
- proto_transitions->length());
-}
-
-
void TransitionArray::SetPrototypeTransitions(
Handle<Map> map, Handle<FixedArray> proto_transitions) {
EnsureHasFullTransitionArray(map);
- if (Heap::ShouldZapGarbage()) {
- Object* raw_transitions = map->raw_transitions();
- DCHECK(raw_transitions != *proto_transitions);
- ZapPrototypeTransitions(raw_transitions);
- }
TransitionArray* transitions = TransitionArray::cast(map->raw_transitions());
transitions->SetPrototypeTransitions(*proto_transitions);
}
@@ -427,7 +454,7 @@ void TransitionArray::EnsureHasFullTransitionArray(Handle<Map> map) {
} else if (nof == 1) {
Map* target = GetSimpleTransition(raw_transitions);
Name* key = GetSimpleTransitionKey(target);
- result->NoIncrementalWriteBarrierSet(0, key, target);
+ result->Set(0, key, target);
}
ReplaceTransitions(map, *result);
}
@@ -444,8 +471,10 @@ void TransitionArray::TraverseTransitionTreeInternal(Map* map,
for (int i = 0; i < NumberOfPrototypeTransitions(proto_trans); ++i) {
int index = TransitionArray::kProtoTransitionHeaderSize + i;
WeakCell* cell = WeakCell::cast(proto_trans->get(index));
- TraverseTransitionTreeInternal(Map::cast(cell->value()), callback,
- data);
+ if (!cell->cleared()) {
+ TraverseTransitionTreeInternal(Map::cast(cell->value()), callback,
+ data);
+ }
}
}
for (int i = 0; i < transitions->number_of_transitions(); ++i) {