Reviewers: rafaelw, rossberg,

Message:
First look at this, no tests yet

Description:
First cut at storing state per-isolate

[email protected]


Please review this at https://codereview.chromium.org/11274014/

SVN Base: http://v8.googlecode.com/svn/branches/bleeding_edge

Affected files:
  M include/v8.h
  M src/heap.h
  M src/heap.cc
  M src/object-observe.js
  M src/runtime.h
  M src/runtime.cc


Index: include/v8.h
diff --git a/include/v8.h b/include/v8.h
index c4a54a46ed712f3d41dedce76f7d42dcc75a8502..ca00202933d906b865cafb9f19da7e3053f9de8c 100644
--- a/include/v8.h
+++ b/include/v8.h
@@ -4096,7 +4096,7 @@ class Internals {
   static const int kNullValueRootIndex = 7;
   static const int kTrueValueRootIndex = 8;
   static const int kFalseValueRootIndex = 9;
-  static const int kEmptySymbolRootIndex = 117;
+  static const int kEmptySymbolRootIndex = 118;

   static const int kJSObjectType = 0xaa;
   static const int kFirstNonstringType = 0x80;
Index: src/heap.cc
diff --git a/src/heap.cc b/src/heap.cc
index 0d2cc42402f4b3457b1d28340984069d452dbd7d..cbbe43b2df2b64b0130980c3ad498be7c97e36c6 100644
--- a/src/heap.cc
+++ b/src/heap.cc
@@ -2814,6 +2814,16 @@ bool Heap::CreateInitialObjects() {
   }
   set_natives_source_cache(FixedArray::cast(obj));

+  // Allocate object to hold object observation state.
+  Map* object_observation_map;
+ { MaybeObject* maybe_obj = AllocateMap(JS_OBJECT_TYPE, JSObject::kHeaderSize);
+    if (!maybe_obj->To(&object_observation_map)) return false;
+  }
+ { MaybeObject* maybe_obj = AllocateJSObjectFromMap(object_observation_map);
+    if (!maybe_obj->ToObject(&obj)) return false;
+  }
+  set_object_observation_state(JSObject::cast(obj));
+
   // Handling of script id generation is in FACTORY->NewScript.
   set_last_script_id(undefined_value());

Index: src/heap.h
diff --git a/src/heap.h b/src/heap.h
index da78b18a512764dae3510e6fcc6dfaa66665e129..179cff8b10f9f54b7a5efbcfbf603f2a5d32eec3 100644
--- a/src/heap.h
+++ b/src/heap.h
@@ -154,7 +154,8 @@ namespace internal {
V(Smi, arguments_adaptor_deopt_pc_offset, ArgumentsAdaptorDeoptPCOffset) \ V(Smi, construct_stub_deopt_pc_offset, ConstructStubDeoptPCOffset) \ V(Smi, getter_stub_deopt_pc_offset, GetterStubDeoptPCOffset) \
-  V(Smi, setter_stub_deopt_pc_offset, SetterStubDeoptPCOffset)
+ V(Smi, setter_stub_deopt_pc_offset, SetterStubDeoptPCOffset) \
+  V(JSObject, object_observation_state, ObjectObservationState)

 #define ROOT_LIST(V)                                  \
   STRONG_ROOT_LIST(V)                                 \
Index: src/object-observe.js
diff --git a/src/object-observe.js b/src/object-observe.js
index 26e23be30dcb6ac267fb54b8b429adff0493fbfc..c2234f08a01ea3a6f6085273b5a00a294206cf99 100644
--- a/src/object-observe.js
+++ b/src/object-observe.js
@@ -43,8 +43,14 @@ function createInternalWeakMap() {
   return map;
 }

-var observerInfoMap = createInternalWeakMap();
-var objectInfoMap = createInternalWeakMap();
+function GetOrCreateObjectObservationState() {
+  var state = %GetObjectObservationState();
+  if (IS_UNDEFINED(state.observerInfoMap)) {
+    state.observerInfoMap = createInternalWeakMap();
+    state.objectInfoMap = createInternalWeakMap();
+  }
+  return state;
+}

 $Object.observe = function(object, callback) {

@@ -55,20 +61,21 @@ $Object.observe = function(object, callback) {
   if (InternalObjectIsFrozen(callback))
     throw MakeTypeError("observe_callback_frozen");

-  if (!observerInfoMap.has(callback)) {
+  var state = GetOrCreateObjectObservationState();
+  if (!state.observerInfoMap.has(callback)) {
     // TODO: setup observerInfo.priority.
-    observerInfoMap.set(callback, {
+    state.observerInfoMap.set(callback, {
       pendingChangeRecords: null
     });
   }

-  var objectInfo = objectInfoMap.get(object);
+  var objectInfo = state.objectInfoMap.get(object);
   if (IS_UNDEFINED(objectInfo)) {
     // TODO: setup objectInfo.notifier
     objectInfo = {
       changeObservers: new InternalArray(callback)
     };
-    objectInfoMap.set(object, objectInfo);
+    state.objectInfoMap.set(object, objectInfo);
     return;
   }

@@ -83,11 +90,12 @@ $Object.unobserve = function(object, callback) {
   if (!IS_SPEC_OBJECT(object))
     throw MakeTypeError("observe_non_object", ["unobserve"]);

-  var objectInfo = objectInfoMap.get(object);
+  var state = GetOrCreateObjectObservationState();
+  var objectInfo = state.objectInfoMap.get(object);
   if (IS_UNDEFINED(objectInfo))
     return;

-  var observerInfo = observerInfoMap.get(callback);
+  var observerInfo = state.observerInfoMap.get(callback);

   var changeObservers = objectInfo.changeObservers;
   var index = changeObservers.indexOf(callback);
@@ -97,10 +105,10 @@ $Object.unobserve = function(object, callback) {
   changeObservers.splice(index, 1);
 }

-function EnqueueChangeRecord(changeRecord, observers) {
+function EnqueueChangeRecord(changeRecord, observers, state) {
   for (var i = 0; i < observers.length; i++) {
     var observer = observers[i];
-    var observerInfo = observerInfoMap.get(observer);
+    var observerInfo = state.observerInfoMap.get(observer);

     // TODO: "activate" the observer

@@ -118,7 +126,8 @@ $Object.notify = function(object, changeRecord) {
   if (!IS_STRING(changeRecord.type))
     throw MakeTypeError("observe_type_non_string");

-  var objectInfo = objectInfoMap.get(object);
+  var state = GetOrCreateObjectObservationState();
+  var objectInfo = state.objectInfoMap.get(object);
   if (IS_UNDEFINED(objectInfo))
     return;

@@ -132,14 +141,15 @@ $Object.notify = function(object, changeRecord) {
   }
   InternalObjectFreeze(newRecord);

-  EnqueueChangeRecord(newRecord, objectInfo.changeObservers);
+  EnqueueChangeRecord(newRecord, objectInfo.changeObservers, state);
 }

 $Object.deliverChangeRecords = function(callback) {
   if (!IS_SPEC_FUNCTION(callback))
     throw MakeTypeError("observe_non_function", ["deliverChangeRecords"]);

-  var observerInfo = observerInfoMap.get(callback);
+  var state = GetOrCreateObjectObservationState();
+  var observerInfo = state.observerInfoMap.get(callback);
   if (IS_UNDEFINED(observerInfo))
     return;

@@ -151,4 +161,4 @@ $Object.deliverChangeRecords = function(callback) {
   var delivered = [];
   %MoveArrayContents(pendingChangeRecords, delivered);
   callback(delivered);
-}
\ No newline at end of file
+}
Index: src/runtime.cc
diff --git a/src/runtime.cc b/src/runtime.cc
index b0a6b5e81427e1588a89f1c269a2b1e90c78f98b..bfe9cc905904f9b50cb675d47dfcae333d6fd9ae 100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -13222,6 +13222,12 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_HaveSameMap) {
   return isolate->heap()->ToBoolean(obj1->map() == obj2->map());
 }

+
+RUNTIME_FUNCTION(MaybeObject*, Runtime_GetObjectObservationState) {
+  ASSERT(args.length() == 0);
+  return isolate->heap()->object_observation_state();
+}
+
// ----------------------------------------------------------------------------
 // Implementation of Runtime

Index: src/runtime.h
diff --git a/src/runtime.h b/src/runtime.h
index c8029065f6908ce9f5d04c695dea00ffb098d687..3c1689f24180726ad6f2a1e5f0bd393bae768241 100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -317,6 +317,9 @@ namespace internal {
   F(WeakMapDelete, 2, 1) \
   F(WeakMapSet, 3, 1) \
   \
+  /* Object observation */ \
+  F(GetObjectObservationState, 0, 1) \
+  \
   /* Statements */ \
   F(NewClosure, 3, 1) \
   F(NewObject, 1, 1) \


--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev

Reply via email to