Revision: 10973
Author:   [email protected]
Date:     Fri Mar  9 00:34:35 2012
Log:      Added support functions for using Literal keys in a HashMap.

This is a preparatory step for using the HashMap clas with Literal keys in the
full code generator. It removes some duplicated code already and removes the
need for 2 HashMaps at each use, which was overly complicated.

Removed one dead function on the way.

Review URL: https://chromiumcodereview.appspot.com/9639011
http://code.google.com/p/v8/source/detail?r=10973

Modified:
 /branches/bleeding_edge/src/ast.cc
 /branches/bleeding_edge/src/ast.h
 /branches/bleeding_edge/src/parser.cc

=======================================
--- /branches/bleeding_edge/src/ast.cc  Thu Mar  8 05:03:07 2012
+++ /branches/bleeding_edge/src/ast.cc  Fri Mar  9 00:34:35 2012
@@ -243,55 +243,21 @@


 void ObjectLiteral::CalculateEmitStore() {
-  ZoneHashMap properties(&IsEqualString);
-  ZoneHashMap elements(&IsEqualNumber);
-  for (int i = this->properties()->length() - 1; i >= 0; i--) {
-    ObjectLiteral::Property* property = this->properties()->at(i);
+  ZoneHashMap table(Literal::Match);
+  for (int i = properties()->length() - 1; i >= 0; i--) {
+    ObjectLiteral::Property* property = properties()->at(i);
     Literal* literal = property->key();
-    Handle<Object> handle = literal->handle();
-
-    if (handle->IsNull()) {
-      continue;
-    }
-
-    uint32_t hash;
-    ZoneHashMap* table;
-    void* key;
-    Factory* factory = Isolate::Current()->factory();
-    if (handle->IsSymbol()) {
-      Handle<String> name(String::cast(*handle));
-      if (name->AsArrayIndex(&hash)) {
-        Handle<Object> key_handle = factory->NewNumberFromUint(hash);
-        key = key_handle.location();
-        table = &elements;
-      } else {
-        key = name.location();
-        hash = name->Hash();
-        table = &properties;
-      }
-    } else if (handle->ToArrayIndex(&hash)) {
-      key = handle.location();
-      table = &elements;
-    } else {
-      ASSERT(handle->IsNumber());
-      double num = handle->Number();
-      char arr[100];
-      Vector<char> buffer(arr, ARRAY_SIZE(arr));
-      const char* str = DoubleToCString(num, buffer);
-      Handle<String> name = factory->NewStringFromAscii(CStrVector(str));
-      key = name.location();
-      hash = name->Hash();
-      table = &properties;
-    }
+    if (literal->handle()->IsNull()) continue;
+    uint32_t hash = literal->Hash();
     // If the key of a computed property is in the table, do not emit
     // a store for the property later.
-    if (property->kind() == ObjectLiteral::Property::COMPUTED) {
-      if (table->Lookup(key, hash, false) != NULL) {
-        property->set_emit_store(false);
-      }
-    }
-    // Add key to the table.
-    table->Lookup(key, hash, true);
+    if (property->kind() == ObjectLiteral::Property::COMPUTED &&
+        table.Lookup(literal, hash, false) != NULL) {
+      property->set_emit_store(false);
+    } else {
+      // Add key to the table.
+      table.Lookup(literal, hash, true);
+    }
   }
 }

@@ -1167,5 +1133,23 @@
     add_flag(kDontInline);
   }
 }
+
+
+Handle<String> Literal::ToString() {
+  if (handle_->IsString()) return Handle<String>::cast(handle_);
+  ASSERT(handle_->IsNumber());
+  char arr[100];
+  Vector<char> buffer(arr, ARRAY_SIZE(arr));
+  const char* str;
+  if (handle_->IsSmi()) {
+    // Optimization only, the heap number case would subsume this.
+    OS::SNPrintF(buffer, "%d", Smi::cast(*handle_)->value());
+    str = arr;
+  } else {
+    str = DoubleToCString(handle_->Number(), buffer);
+  }
+  return FACTORY->NewStringFromAscii(CStrVector(str));
+}
+

 } }  // namespace v8::internal
=======================================
--- /branches/bleeding_edge/src/ast.h   Thu Mar  8 05:03:07 2012
+++ /branches/bleeding_edge/src/ast.h   Fri Mar  9 00:34:35 2012
@@ -1210,11 +1210,6 @@
 class Literal: public Expression {
  public:
   DECLARE_NODE_TYPE(Literal)
-
-  // Check if this literal is identical to the other literal.
-  bool IsIdenticalTo(const Literal* other) const {
-    return handle_.is_identical_to(other->handle_);
-  }

   virtual bool IsPropertyName() {
     if (handle_->IsSymbol()) {
@@ -1247,6 +1242,16 @@
   }

   Handle<Object> handle() const { return handle_; }
+
+ // Support for using Literal as a HashMap key. NOTE: Currently, this works
+  // only for string and number literals!
+  uint32_t Hash() { return ToString()->Hash(); }
+
+  static bool Match(void* literal1, void* literal2) {
+    Handle<String> s1 = static_cast<Literal*>(literal1)->ToString();
+    Handle<String> s2 = static_cast<Literal*>(literal2)->ToString();
+    return s1->Equals(*s2);
+  }

  protected:
   template<class> friend class AstNodeFactory;
@@ -1256,6 +1261,8 @@
         handle_(handle) { }

  private:
+  Handle<String> ToString();
+
   Handle<Object> handle_;
 };

=======================================
--- /branches/bleeding_edge/src/parser.cc       Thu Mar  8 05:03:07 2012
+++ /branches/bleeding_edge/src/parser.cc       Fri Mar  9 00:34:35 2012
@@ -3898,18 +3898,12 @@
   }
   return isolate()->factory()->undefined_value();
 }
-
-// Defined in ast.cc
-bool IsEqualString(void* first, void* second);
-bool IsEqualNumber(void* first, void* second);
-

 // Validation per 11.1.5 Object Initialiser
 class ObjectLiteralPropertyChecker {
  public:
ObjectLiteralPropertyChecker(Parser* parser, LanguageMode language_mode) :
-    props(&IsEqualString),
-    elems(&IsEqualNumber),
+    props_(Literal::Match),
     parser_(parser),
     language_mode_(language_mode) {
   }
@@ -3938,8 +3932,7 @@
     }
   }

-  HashMap props;
-  HashMap elems;
+  HashMap props_;
   Parser* parser_;
   LanguageMode language_mode_;
 };
@@ -3949,44 +3942,9 @@
     ObjectLiteral::Property* property,
     Scanner::Location loc,
     bool* ok) {
-
   ASSERT(property != NULL);
-
-  Literal* lit = property->key();
-  Handle<Object> handle = lit->handle();
-
-  uint32_t hash;
-  HashMap* map;
-  void* key;
-
-  if (handle->IsSymbol()) {
-    Handle<String> name(String::cast(*handle));
-    if (name->AsArrayIndex(&hash)) {
-      Handle<Object> key_handle = FACTORY->NewNumberFromUint(hash);
-      key = key_handle.location();
-      map = &elems;
-    } else {
-      key = handle.location();
-      hash = name->Hash();
-      map = &props;
-    }
-  } else if (handle->ToArrayIndex(&hash)) {
-    key = handle.location();
-    map = &elems;
-  } else {
-    ASSERT(handle->IsNumber());
-    double num = handle->Number();
-    char arr[100];
-    Vector<char> buffer(arr, ARRAY_SIZE(arr));
-    const char* str = DoubleToCString(num, buffer);
-    Handle<String> name = FACTORY->NewStringFromAscii(CStrVector(str));
-    key = name.location();
-    hash = name->Hash();
-    map = &props;
-  }
-
-  // Lookup property previously defined, if any.
-  HashMap::Entry* entry = map->Lookup(key, hash, true);
+  Literal* literal = property->key();
+  HashMap::Entry* entry = props_.Lookup(literal, literal->Hash(), true);
   intptr_t prev = reinterpret_cast<intptr_t> (entry->value);
   intptr_t curr = GetPropertyKind(property);

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

Reply via email to