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

Unified Diff: src/elements.cc

Issue 7529046: Refactor UnionOfKeys into ElementsAccessor (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: review feedback Created 9 years, 4 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/elements.h ('k') | src/objects.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/elements.cc
diff --git a/src/elements.cc b/src/elements.cc
index 45ab2d9aa8a30e9b1ef2f7dfed104e1c19633d2a..9cfcceec24cadeea63fd15c452cff71a3b08caf8 100644
--- a/src/elements.cc
+++ b/src/elements.cc
@@ -37,6 +37,20 @@ namespace internal {
ElementsAccessor** ElementsAccessor::elements_accessors_;
+bool HasKey(FixedArray* array, Object* key) {
+ int len0 = array->length();
+ for (int i = 0; i < len0; i++) {
+ Object* element = array->get(i);
+ if (element->IsSmi() && element == key) return true;
+ if (element->IsString() &&
+ key->IsString() && String::cast(element)->Equals(String::cast(key))) {
+ return true;
+ }
+ }
+ return false;
+}
+
+
// Base class for element handler implementations. Contains the
// the common logic for objects with different ElementsKinds.
// Subclasses must specialize method for which the element
@@ -73,6 +87,78 @@ class ElementsAccessorBase : public ElementsAccessor {
uint32_t index,
JSReceiver::DeleteMode mode) = 0;
+ virtual MaybeObject* AddJSArrayKeysToFixedArray(JSArray* other,
+ FixedArray* keys) {
+ int len0 = keys->length();
+#ifdef DEBUG
+ if (FLAG_enable_slow_asserts) {
+ for (int i = 0; i < len0; i++) {
+ ASSERT(keys->get(i)->IsString() || keys->get(i)->IsNumber());
+ }
+ }
+#endif
+ int len1 = ElementsAccessorSubclass::GetCapacity(other);
+
+ // Optimize if 'other' is empty.
+ // We cannot optimize if 'this' is empty, as other may have holes
+ // or non keys.
+ if (len1 == 0) return keys;
+
+ // Compute how many elements are not in other.
+ int extra = 0;
+ for (int y = 0; y < len1; y++) {
+ Object* value;
+ MaybeObject* maybe_value =
+ ElementsAccessorSubclass::GetElementAtCapacityIndex(other, y);
+ if (!maybe_value->ToObject(&value)) return maybe_value;
+ if (!value->IsTheHole() && !HasKey(keys, value)) extra++;
+ }
+
+ if (extra == 0) return keys;
+
+ // Allocate the result
+ FixedArray* result;
+ MaybeObject* maybe_obj =
+ other->GetHeap()->AllocateFixedArray(len0 + extra);
+ if (!maybe_obj->To<FixedArray>(&result)) return maybe_obj;
+
+ // Fill in the content
+ {
+ AssertNoAllocation no_gc;
+ WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc);
+ for (int i = 0; i < len0; i++) {
+ Object* e = keys->get(i);
+ ASSERT(e->IsString() || e->IsNumber());
+ result->set(i, e, mode);
+ }
+ }
+ // Fill in the extra keys.
+ int index = 0;
+ for (int y = 0; y < len1; y++) {
+ MaybeObject* maybe_value =
+ ElementsAccessorSubclass::GetElementAtCapacityIndex(other, y);
+ Object* value;
+ if (!maybe_value->ToObject(&value)) return maybe_value;
+ if (!value->IsTheHole() && !HasKey(keys, value)) {
+ ASSERT(value->IsString() || value->IsNumber());
+ result->set(len0 + index, value);
+ index++;
+ }
+ }
+ ASSERT(extra == index);
+ return result;
+ }
+
+ static uint32_t GetCapacity(JSObject* obj) {
+ return ElementsAccessorSubclass::GetBackingStore(obj)->length();
+ }
+
+ static MaybeObject* GetElementAtCapacityIndex(JSObject* obj, int index) {
+ BackingStoreClass* backing_store =
+ ElementsAccessorSubclass::GetBackingStore(obj);
+ return backing_store->get(index);
+ }
+
protected:
static BackingStoreClass* GetBackingStore(JSObject* obj) {
return BackingStoreClass::cast(obj->elements());
@@ -325,6 +411,19 @@ class DictionaryElementsAccessor
obj->element_dictionary(),
index);
}
+
+ static uint32_t GetCapacity(JSObject* obj) {
+ return obj->element_dictionary()->Capacity();
+ }
+
+ static MaybeObject* GetElementAtCapacityIndex(JSObject* obj, int index) {
+ NumberDictionary* dict = obj->element_dictionary();
+ if (dict->IsKey(dict->KeyAt(index))) {
+ return dict->ValueAt(index);
+ } else {
+ return obj->GetHeap()->the_hole_value();
+ }
+ }
};
@@ -382,6 +481,18 @@ class NonStrictArgumentsElementsAccessor
}
return obj->GetHeap()->true_value();
}
+
+ static uint32_t GetCapacity(JSObject* obj) {
+ // TODO(danno): Return max of parameter map length or backing store
+ // capacity.
+ return 0;
+ }
+
+ static MaybeObject* GetElementAtCapacityIndex(JSObject* obj, int index) {
+ // TODO(danno): Return either value from parameter map of backing
+ // store value at index.
+ return obj->GetHeap()->the_hole_value();
+ }
};
« no previous file with comments | « src/elements.h ('k') | src/objects.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698