Reviewers: Toon Verwaest,

Description:
Version 3.28.71.18 (merged r24849)

Fixed mutable heap numbers leak in JSON parser.

BUG=chromium:423687
LOG=N
[email protected]

Please review this at https://codereview.chromium.org/698153004/

Base URL: https://v8.googlecode.com/svn/branches/3.28

Affected files (+46, -22 lines):
  M src/json-parser.h
  M src/version.cc
  A + test/mjsunit/regress/regress-crbug-423687.js


Index: src/json-parser.h
diff --git a/src/json-parser.h b/src/json-parser.h
index cf3e6b82b17092e2b03945035ed650b64cf8a4b9..19cffde0c9a752a6813f039164bf328e1a2307d4 100644
--- a/src/json-parser.h
+++ b/src/json-parser.h
@@ -182,6 +182,9 @@ class JsonParser BASE_EMBEDDED {
  private:
   Zone* zone() { return &zone_; }

+ void CommitStateToJsonObject(Handle<JSObject> json_object, Handle<Map> map,
+                               ZoneList<Handle<Object> >* properties);
+
   Handle<String> source_;
   int source_length_;
   Handle<SeqOneByteString> seq_source_;
@@ -408,13 +411,7 @@ Handle<Object> JsonParser<seq_ascii>::ParseJsonObject() {
         }

// Commit the intermediate state to the object and stop transitioning.
-        JSObject::AllocateStorageForMap(json_object, map);
-        int length = properties.length();
-        for (int i = 0; i < length; i++) {
-          Handle<Object> value = properties[i];
-          FieldIndex index = FieldIndex::ForPropertyIndex(*map, i);
-          json_object->FastPropertyAtPut(index, *value);
-        }
+        CommitStateToJsonObject(json_object, map, &properties);
       } else {
         key = ParseJsonInternalizedString();
if (key.is_null() || c0_ != ':') return ReportUnexpectedCharacter(); @@ -432,19 +429,50 @@ Handle<Object> JsonParser<seq_ascii>::ParseJsonObject() {

     // If we transitioned until the very end, transition the map now.
     if (transitioning) {
-      JSObject::AllocateStorageForMap(json_object, map);
-      int length = properties.length();
-      for (int i = 0; i < length; i++) {
-        Handle<Object> value = properties[i];
-        FieldIndex index = FieldIndex::ForPropertyIndex(*map, i);
-        json_object->FastPropertyAtPut(index, *value);
-      }
+      CommitStateToJsonObject(json_object, map, &properties);
     }
   }
   AdvanceSkipWhitespace();
   return scope.CloseAndEscape(json_object);
 }

+
+template <bool seq_one_byte>
+void JsonParser<seq_one_byte>::CommitStateToJsonObject(
+    Handle<JSObject> json_object, Handle<Map> map,
+    ZoneList<Handle<Object> >* properties) {
+  JSObject::AllocateStorageForMap(json_object, map);
+  DCHECK(!json_object->map()->is_dictionary_map());
+
+  DisallowHeapAllocation no_gc;
+  Factory* factory = isolate()->factory();
+  // If the |json_object|'s map is exactly the same as |map| then the
+  // |properties| values correspond to the |map| and nothing more has to be
+  // done. But if the |json_object|'s map is different then we have to
+  // iterate descriptors to ensure that properties still correspond to the
+  // map.
+  bool slow_case = json_object->map() != *map;
+  DescriptorArray* descriptors = NULL;
+
+  int length = properties->length();
+  if (slow_case) {
+    descriptors = json_object->map()->instance_descriptors();
+    DCHECK(json_object->map()->NumberOfOwnDescriptors() == length);
+  }
+  for (int i = 0; i < length; i++) {
+    Handle<Object> value = (*properties)[i];
+    if (slow_case && value->IsMutableHeapNumber() &&
+        !descriptors->GetDetails(i).representation().IsDouble()) {
+ // Turn mutable heap numbers into immutable if the field representation
+      // is not double.
+      HeapNumber::cast(*value)->set_map(*factory->heap_number_map());
+    }
+    FieldIndex index = FieldIndex::ForPropertyIndex(*map, i);
+    json_object->FastPropertyAtPut(index, *value);
+  }
+}
+
+
 // Parse a JSON array. Position must be right at '['.
 template <bool seq_ascii>
 Handle<Object> JsonParser<seq_ascii>::ParseJsonArray() {
Index: src/version.cc
diff --git a/src/version.cc b/src/version.cc
index 890a67089eb1ee773d561a1b5b3e0bb2d1a1aa8e..3f52f97ccf96f004d82231944e283d43462b9759 100644
--- a/src/version.cc
+++ b/src/version.cc
@@ -35,7 +35,7 @@
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     28
 #define BUILD_NUMBER      71
-#define PATCH_LEVEL 17
+#define PATCH_LEVEL 18
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
 #define IS_CANDIDATE_VERSION 0
Index: test/mjsunit/regress/regress-crbug-423687.js
diff --git a/test/mjsunit/regress/regress-crbug-387636.js b/test/mjsunit/regress/regress-crbug-423687.js
similarity index 67%
copy from test/mjsunit/regress/regress-crbug-387636.js
copy to test/mjsunit/regress/regress-crbug-423687.js
index 1e50ace45a293c8561042f1a09c8fcd505b43dc2..60003527e81453b895ee8ad5b9c3517a5648ff8f 100644
--- a/test/mjsunit/regress/regress-crbug-387636.js
+++ b/test/mjsunit/regress/regress-crbug-423687.js
@@ -4,11 +4,7 @@

 // Flags: --allow-natives-syntax

-function f() {
-  [].indexOf(0x40000000);
-}
+var json = '{"a":{"c":2.1,"d":0},"b":{"c":7,"1024":8}}';
+var data = JSON.parse(json);

-f();
-f();
-%OptimizeFunctionOnNextCall(f);
-f();
+data.b.c++;


--
--
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/d/optout.

Reply via email to