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

Unified Diff: src/objects.cc

Issue 18221006: Add map transition for observed objects (Closed) Base URL: https://github.com/v8/v8.git@bleeding_edge
Patch Set: better check Created 7 years, 5 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 side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/objects.h ('k') | src/runtime.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/objects.cc
diff --git a/src/objects.cc b/src/objects.cc
index 3e7a5e9c424450105e1495149c2c5d572d2a8524..7b06b8732ad03928d97d3dfcf16483b7633a39c5 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -4018,7 +4018,7 @@ MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes(
Handle<Object> old_value(isolate->heap()->the_hole_value(), isolate);
PropertyAttributes old_attributes = ABSENT;
bool is_observed = FLAG_harmony_observation && self->map()->is_observed();
- if (is_observed) {
+ if (is_observed && lookup.IsProperty()) {
if (lookup.IsDataProperty()) old_value = Object::GetProperty(self, name);
old_attributes = lookup.GetAttributes();
}
@@ -5557,6 +5557,40 @@ MUST_USE_RESULT MaybeObject* JSObject::Freeze(Isolate* isolate) {
}
+MUST_USE_RESULT MaybeObject* JSObject::SetObserved(Isolate* isolate) {
+ if (map()->is_observed())
+ return isolate->heap()->undefined_value();
+
+ Heap* heap = isolate->heap();
+
+ if (!HasExternalArrayElements()) {
+ // Go to dictionary mode, so that we don't skip map checks.
+ MaybeObject* maybe = NormalizeElements();
+ if (maybe->IsFailure()) return maybe;
+ ASSERT(!HasFastElements());
+ }
+
+ LookupResult result(isolate);
+ map()->LookupTransition(this, heap->observed_symbol(), &result);
+
+ Map* new_map;
+ if (result.IsTransition()) {
+ new_map = result.GetTransitionTarget();
+ ASSERT(new_map->is_observed());
+ } else if (map()->CanHaveMoreTransitions()) {
+ MaybeObject* maybe_new_map = map()->CopyForObserved();
+ if (!maybe_new_map->To(&new_map)) return maybe_new_map;
+ } else {
+ MaybeObject* maybe_copy = map()->Copy();
+ if (!maybe_copy->To(&new_map)) return maybe_copy;
+ new_map->set_is_observed(true);
+ }
+ set_map(new_map);
+
+ return heap->undefined_value();
+}
+
+
MUST_USE_RESULT MaybeObject* JSObject::DeepCopy(Isolate* isolate) {
StackLimitCheck check(isolate);
if (check.HasOverflowed()) return isolate->StackOverflow();
@@ -6680,6 +6714,39 @@ MaybeObject* Map::CopyAsElementsKind(ElementsKind kind, TransitionFlag flag) {
}
+MaybeObject* Map::CopyForObserved() {
+ ASSERT(!is_observed());
+
+ // In case the map owned its own descriptors, share the descriptors and
+ // transfer ownership to the new map.
+ Map* new_map;
+ MaybeObject* maybe_new_map;
+ if (owns_descriptors()) {
+ maybe_new_map = CopyDropDescriptors();
+ } else {
+ maybe_new_map = Copy();
+ }
+ if (!maybe_new_map->To(&new_map)) return maybe_new_map;
+
+ TransitionArray* transitions;
+ MaybeObject* maybe_transitions = AddTransition(GetHeap()->observed_symbol(),
+ new_map,
+ FULL_TRANSITION);
+ if (!maybe_transitions->To(&transitions)) return maybe_transitions;
+ set_transitions(transitions);
+
+ new_map->set_is_observed(true);
+
+ if (owns_descriptors()) {
+ new_map->InitializeDescriptors(instance_descriptors());
+ set_owns_descriptors(false);
+ }
+
+ new_map->SetBackPointer(this);
+ return new_map;
+}
+
+
MaybeObject* Map::CopyWithPreallocatedFieldDescriptors() {
if (pre_allocated_property_fields() == 0) return CopyDropDescriptors();
« no previous file with comments | « src/objects.h ('k') | src/runtime.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698