Adding hidden values always turned the object slow case because the
authorager@chromium.org <ager@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 22 Apr 2009 07:38:08 +0000 (07:38 +0000)
committerager@chromium.org <ager@chromium.org@ce2b1a6d-e550-0410-aec6-3dcde31c8c00>
Wed, 22 Apr 2009 07:38:08 +0000 (07:38 +0000)
hidden symbol is not an identifier.  Make sure to keep objects fast
case when adding hidden values if possible.
Review URL: http://codereview.chromium.org/93004

git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1758 ce2b1a6d-e550-0410-aec6-3dcde31c8c00

src/objects.cc

index 21b0ee4..31c5bab 100644 (file)
@@ -1129,9 +1129,10 @@ Object* JSObject::AddFastPropertyUsingMap(Map* new_map,
 Object* JSObject::AddFastProperty(String* name,
                                   Object* value,
                                   PropertyAttributes attributes) {
-  // Normalize the object if the name is not a real identifier.
+  // Normalize the object if the name is an actual string (not the
+  // hidden symbols) and is not a real identifier.
   StringInputBuffer buffer(name);
-  if (!Scanner::IsIdentifier(&buffer)) {
+  if (!Scanner::IsIdentifier(&buffer) && name != Heap::hidden_symbol()) {
     Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES);
     if (obj->IsFailure()) return obj;
     return AddSlowProperty(name, value, attributes);
@@ -5172,19 +5173,15 @@ bool JSObject::HasLocalElement(uint32_t index) {
 Object* JSObject::GetHiddenProperties(bool create_if_needed) {
   String* key = Heap::hidden_symbol();
   if (this->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 it will always occupy the first entry if present.
+    // 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 = this->map()->instance_descriptors();
-    if (descriptors->number_of_descriptors() > 0) {
-      if (descriptors->GetKey(0) == key) {
-#ifdef DEBUG
-        PropertyDetails details(descriptors->GetDetails(0));
-        ASSERT(details.type() == FIELD);
-#endif  // DEBUG
-        Object* value = descriptors->GetValue(0);
-        return FastPropertyAt(Descriptor::IndexFromValue(value));
-      }
+    DescriptorReader r(descriptors);
+    if (!r.eos() && (r.GetKey() == key) && r.IsProperty()) {
+      ASSERT(r.type() == FIELD);
+      return FastPropertyAt(r.GetFieldIndex());
     }
   }