Reviewers: rossberg, Michael Starzinger,
Message:
Note that I haven't added any tests. The existing tests didn't depend on the
weakness of the maps. Suggestions on how to test that weakness welcome.
Also, note that I've put a TODO in ObservationWeakMapCreate: right now I
create
a new map for each JSWeakMap, which seems a little wasteful, but there are
only
three of them. Let me know if it's worth moving that handle to the strong
roots
list now.
Description:
Object.observe: use JSWeakMaps instead of raw ObjectHashTables in
observation
state
object-observe.js uses weak maps to add "hidden" properties to
objects. Previously, the hash tables it was using weren't actually
weak. This patch changes the existing runtime functions to create
instances of JSWeakMap instead of exposing ObjectHashTable directly.
Please review this at https://codereview.chromium.org/12092079/
SVN Base: https://v8.googlecode.com/svn/branches/bleeding_edge
Affected files:
M src/object-observe.js
M src/runtime.h
M src/runtime.cc
Index: src/object-observe.js
diff --git a/src/object-observe.js b/src/object-observe.js
index
d0a84f69c3eec5e45eec71043bdc52cccb829759..f30b3e4bf1ae30b353373a679f95b45ac854e8f1
100644
--- a/src/object-observe.js
+++ b/src/object-observe.js
@@ -29,33 +29,32 @@
var observationState = %GetObservationState();
if (IS_UNDEFINED(observationState.observerInfoMap)) {
- observationState.observerInfoMap = %CreateObjectHashTable();
- observationState.objectInfoMap = %CreateObjectHashTable();
- observationState.notifierTargetMap = %CreateObjectHashTable();
+ observationState.observerInfoMap = %ObservationWeakMapCreate();
+ observationState.objectInfoMap = %ObservationWeakMapCreate();
+ observationState.notifierTargetMap = %ObservationWeakMapCreate();
observationState.pendingObservers = new InternalArray;
observationState.observerPriority = 0;
}
-function InternalObjectHashTable(tableName) {
+function ObservationWeakMap(tableName) {
this.tableName = tableName;
}
-InternalObjectHashTable.prototype = {
+ObservationWeakMap.prototype = {
get: function(key) {
- return %ObjectHashTableGet(observationState[this.tableName], key);
+ return %ObservationWeakMapGet(observationState[this.tableName], key);
},
set: function(key, value) {
- observationState[this.tableName] =
- %ObjectHashTableSet(observationState[this.tableName], key, value);
+ %ObservationWeakMapSet(observationState[this.tableName], key, value);
},
has: function(key) {
return !IS_UNDEFINED(this.get(key));
}
};
-var observerInfoMap = new InternalObjectHashTable('observerInfoMap');
-var objectInfoMap = new InternalObjectHashTable('objectInfoMap');
-var notifierTargetMap = new InternalObjectHashTable('notifierTargetMap');
+var observerInfoMap = new ObservationWeakMap('observerInfoMap');
+var objectInfoMap = new ObservationWeakMap('objectInfoMap');
+var notifierTargetMap = new ObservationWeakMap('notifierTargetMap');
function CreateObjectInfo(object) {
var info = {
Index: src/runtime.cc
diff --git a/src/runtime.cc b/src/runtime.cc
index
e8003b6731cc77740ed36596a90a59fcfe957027..49b4731e4cb3dc19da2727a0e62baba301dffe6f
100644
--- a/src/runtime.cc
+++ b/src/runtime.cc
@@ -863,10 +863,7 @@ RUNTIME_FUNCTION(MaybeObject*, Runtime_MapGetSize) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapInitialize) {
- HandleScope scope(isolate);
- ASSERT(args.length() == 1);
- CONVERT_ARG_HANDLE_CHECKED(JSWeakMap, weakmap, 0);
+static JSWeakMap* WeakMapInitialize(Isolate* isolate, Handle<JSWeakMap>
weakmap) {
ASSERT(weakmap->map()->inobject_properties() == 0);
Handle<ObjectHashTable> table =
isolate->factory()->NewObjectHashTable(0);
weakmap->set_table(*table);
@@ -875,6 +872,14 @@ RUNTIME_FUNCTION(MaybeObject*,
Runtime_WeakMapInitialize) {
}
+RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapInitialize) {
+ HandleScope scope(isolate);
+ ASSERT(args.length() == 1);
+ CONVERT_ARG_HANDLE_CHECKED(JSWeakMap, weakmap, 0);
+ return WeakMapInitialize(isolate, weakmap);
+}
+
+
RUNTIME_FUNCTION(MaybeObject*, Runtime_WeakMapGet) {
HandleScope scope(isolate);
ASSERT(args.length() == 2);
@@ -13404,16 +13409,25 @@ RUNTIME_FUNCTION(MaybeObject*,
Runtime_GetObservationState) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_CreateObjectHashTable) {
+RUNTIME_FUNCTION(MaybeObject*, Runtime_ObservationWeakMapCreate) {
+ HandleScope scope(isolate);
ASSERT(args.length() == 0);
- return ObjectHashTable::Allocate(0);
+ // TODO(adamk): Currently this runtime function is only called three
times per
+ // isolate. If it's called more often, the map should be moved into the
+ // strong root list.
+ Handle<Map> map =
+ isolate->factory()->NewMap(JS_WEAK_MAP_TYPE, JSWeakMap::kSize);
+ Handle<JSWeakMap> weakmap =
+ Handle<JSWeakMap>::cast(isolate->factory()->NewJSObjectFromMap(map));
+ return WeakMapInitialize(isolate, weakmap);
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_ObjectHashTableGet) {
+RUNTIME_FUNCTION(MaybeObject*, Runtime_ObservationWeakMapGet) {
NoHandleAllocation ha;
ASSERT(args.length() == 2);
- CONVERT_ARG_CHECKED(ObjectHashTable, table, 0);
+ CONVERT_ARG_CHECKED(JSWeakMap, weakmap, 0);
+ ObjectHashTable* table = ObjectHashTable::cast(weakmap->table());
Object* key = args[1];
if (key->IsJSGlobalProxy()) {
key = key->GetPrototype();
@@ -13424,17 +13438,20 @@ RUNTIME_FUNCTION(MaybeObject*,
Runtime_ObjectHashTableGet) {
}
-RUNTIME_FUNCTION(MaybeObject*, Runtime_ObjectHashTableSet) {
+RUNTIME_FUNCTION(MaybeObject*, Runtime_ObservationWeakMapSet) {
HandleScope scope(isolate);
ASSERT(args.length() == 3);
- CONVERT_ARG_HANDLE_CHECKED(ObjectHashTable, table, 0);
+ CONVERT_ARG_HANDLE_CHECKED(JSWeakMap, weakmap, 0);
+ Handle<ObjectHashTable> table(ObjectHashTable::cast(weakmap->table()));
Handle<Object> key = args.at<Object>(1);
if (key->IsJSGlobalProxy()) {
key = handle(key->GetPrototype(), isolate);
- if (key->IsNull()) return *table;
+ if (key->IsNull()) return isolate->heap()->undefined_value();
}
Handle<Object> value = args.at<Object>(2);
- return *PutIntoObjectHashTable(table, key, value);
+ table = PutIntoObjectHashTable(table, key, value);
+ weakmap->set_table(*table);
+ return isolate->heap()->undefined_value();
}
Index: src/runtime.h
diff --git a/src/runtime.h b/src/runtime.h
index
0bdc81179241352dd2e71948d390d4a10b22f018..4793be85995b7a359e2331457c950a3ad76b727d
100644
--- a/src/runtime.h
+++ b/src/runtime.h
@@ -333,9 +333,9 @@ namespace internal {
F(SetIsObserved, 2, 1) \
F(SetObserverDeliveryPending, 0, 1) \
F(GetObservationState, 0, 1) \
- F(CreateObjectHashTable, 0, 1) \
- F(ObjectHashTableGet, 2, 1) \
- F(ObjectHashTableSet, 3, 1) \
+ F(ObservationWeakMapCreate, 0, 1) \
+ F(ObservationWeakMapGet, 2, 1) \
+ F(ObservationWeakMapSet, 3, 1) \
\
/* Statements */ \
F(NewClosure, 3, 1) \
--
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev
---
You received this message because you are subscribed to the Google Groups "v8-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/groups/opt_out.