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

Unified Diff: src/objects.cc

Issue 7349005: Added dictionary that can use objects as keys. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Added unit test to gyp buildfile as well. Created 9 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/objects-inl.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 4d70b32147318bdd8f27add24dac5245c1dd8230..fc6596ccd404af15056f923097049f35da83883d 100644
--- a/src/objects.cc
+++ b/src/objects.cc
@@ -2894,6 +2894,84 @@ MaybeObject* JSObject::NormalizeElements() {
}
+MaybeObject* JSObject::GetHiddenProperties(bool create_if_needed) {
+ Isolate* isolate = GetIsolate();
+ Heap* heap = isolate->heap();
+ if (HasFastProperties()) {
+ // If the object has fast properties, check whether the first slot
+ // in the descriptor array matches the hidden symbol. Since the
+ // hidden symbols hash code is zero (and no other string has hash
+ // code zero) it will always occupy the first entry if present.
+ DescriptorArray* descriptors = map()->instance_descriptors();
+ if ((descriptors->number_of_descriptors() > 0) &&
+ (descriptors->GetKey(0) == heap->hidden_symbol()) &&
+ descriptors->IsProperty(0)) {
+ ASSERT(descriptors->GetType(0) == FIELD);
+ return FastPropertyAt(descriptors->GetFieldIndex(0));
+ }
+ }
+
+ // Only attempt to find the hidden properties in the local object and not
+ // in the prototype chain. Note that HasLocalProperty() can cause a GC in
+ // the general case in the presence of interceptors.
+ if (!HasHiddenPropertiesObject()) {
+ // Hidden properties object not found. Allocate a new hidden properties
+ // object if requested. Otherwise return the undefined value.
+ if (create_if_needed) {
+ Object* hidden_obj;
+ { MaybeObject* maybe_obj = heap->AllocateJSObject(
+ isolate->context()->global_context()->object_function());
+ if (!maybe_obj->ToObject(&hidden_obj)) return maybe_obj;
+ }
+ return SetHiddenPropertiesObject(hidden_obj);
+ } else {
+ return heap->undefined_value();
+ }
+ }
+ return GetHiddenPropertiesObject();
+}
+
+
+MaybeObject* JSObject::GetIdentityHash() {
+ Isolate* isolate = GetIsolate();
+ Object* hidden_props_obj;
+ { MaybeObject* maybe_obj = GetHiddenProperties(true);
+ if (!maybe_obj->ToObject(&hidden_props_obj)) return maybe_obj;
+ }
+ if (!hidden_props_obj->IsJSObject()) {
+ // We failed to create hidden properties. That's a detached
+ // global proxy.
+ ASSERT(hidden_props_obj->IsUndefined());
+ return Smi::FromInt(0);
+ }
+ JSObject* hidden_props = JSObject::cast(hidden_props_obj);
+ String* hash_symbol = isolate->heap()->identity_hash_symbol();
+ if (hidden_props->HasLocalProperty(hash_symbol)) {
+ MaybeObject* hash = hidden_props->GetProperty(hash_symbol);
+ return Smi::cast(hash->ToObjectChecked());
+ }
+
+ int hash_value;
+ int attempts = 0;
+ do {
+ // Generate a random 32-bit hash value but limit range to fit
+ // within a smi.
+ hash_value = V8::Random(isolate) & Smi::kMaxValue;
+ attempts++;
+ } while (hash_value == 0 && attempts < 30);
+ hash_value = hash_value != 0 ? hash_value : 1; // never return 0
+
+ Smi* hash = Smi::FromInt(hash_value);
+ { MaybeObject* result = hidden_props->SetLocalPropertyIgnoreAttributes(
+ hash_symbol,
+ hash,
+ static_cast<PropertyAttributes>(None));
+ if (result->IsFailure()) return result;
+ }
+ return hash;
+}
+
+
MaybeObject* JSObject::DeletePropertyPostInterceptor(String* name,
DeleteMode mode) {
// Check local property, ignore interceptor.
@@ -10138,12 +10216,17 @@ template class Dictionary<StringDictionaryShape, String*>;
template class Dictionary<NumberDictionaryShape, uint32_t>;
+template class Dictionary<ObjectDictionaryShape, JSObject*>;
+
template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::Allocate(
int);
template MaybeObject* Dictionary<StringDictionaryShape, String*>::Allocate(
int);
+template MaybeObject* Dictionary<ObjectDictionaryShape, JSObject*>::Allocate(
+ int);
+
template MaybeObject* Dictionary<NumberDictionaryShape, uint32_t>::AtPut(
uint32_t, Object*);
@@ -10181,6 +10264,9 @@ Dictionary<StringDictionaryShape, String*>::NumberOfElementsFilterAttributes(
template MaybeObject* Dictionary<StringDictionaryShape, String*>::Add(
String*, Object*, PropertyDetails);
+template MaybeObject* Dictionary<ObjectDictionaryShape, JSObject*>::Add(
+ JSObject*, Object*, PropertyDetails);
+
template MaybeObject*
Dictionary<StringDictionaryShape, String*>::GenerateNewEnumerationIndices();
@@ -11140,7 +11226,8 @@ MaybeObject* Dictionary<Shape, Key>::AddEntry(Key key,
}
SetEntry(entry, k, value, details);
ASSERT((Dictionary<Shape, Key>::KeyAt(entry)->IsNumber()
- || Dictionary<Shape, Key>::KeyAt(entry)->IsString()));
+ || Dictionary<Shape, Key>::KeyAt(entry)->IsString()
+ || Dictionary<Shape, Key>::KeyAt(entry)->IsJSObject()));
HashTable<Shape, Key>::ElementAdded();
return this;
}
@@ -11445,6 +11532,15 @@ MaybeObject* StringDictionary::TransformPropertiesToFastFor(
}
+MaybeObject* ObjectDictionary::AddChecked(JSObject* key, Object* value) {
+ // Make sure the key object has an identity hash code.
+ MaybeObject* maybe_hash = key->GetIdentityHash();
+ if (maybe_hash->IsFailure()) return maybe_hash;
+ PropertyDetails details(NONE, NORMAL);
+ return Add(key, value, details);
+}
+
+
#ifdef ENABLE_DEBUGGER_SUPPORT
// Check if there is a break point at this code position.
bool DebugInfo::HasBreakPoint(int code_position) {
« no previous file with comments | « src/objects.h ('k') | src/objects-inl.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698