deps: cherry-pick r21466 from v8 trunk
authorBen Noordhuis <info@bnoordhuis.nl>
Fri, 23 May 2014 14:01:17 +0000 (14:01 +0000)
committerFedor Indutny <fedor@indutny.com>
Fri, 13 Jun 2014 00:46:18 +0000 (17:46 -0700)
Check for cached transition to ExternalArray elements kind.
See [1] and [2] for details.

[1] https://code.google.com/p/v8/issues/detail?id=3337
[2] https://codereview.chromium.org/291193011

Signed-off-by: Fedor Indutny <fedor@indutny.com>
deps/v8/src/objects.cc
deps/v8/test/cctest/test-api.cc

index 956e46f..8aa2eb1 100644 (file)
@@ -3362,9 +3362,16 @@ static Map* FindClosestElementsTransition(Map* map, ElementsKind to_kind) {
       ? to_kind
       : TERMINAL_FAST_ELEMENTS_KIND;
 
-  // Support for legacy API.
+  // Support for legacy API: SetIndexedPropertiesTo{External,Pixel}Data
+  // allows to change elements from arbitrary kind to any ExternalArray
+  // elements kind. Satisfy its requirements, checking whether we already
+  // have the cached transition.
   if (IsExternalArrayElementsKind(to_kind) &&
       !IsFixedTypedArrayElementsKind(map->elements_kind())) {
+    if (map->HasElementsTransition()) {
+        Map* next_map = map->elements_transition_map();
+        if (next_map->elements_kind() == to_kind) return next_map;
+    }
     return map;
   }
 
index d8fa648..14df05a 100644 (file)
@@ -21341,6 +21341,23 @@ THREADED_TEST(Regress142088) {
 }
 
 
+THREADED_TEST(Regress3337) {
+  LocalContext context;
+  v8::Isolate* isolate = context->GetIsolate();
+  v8::HandleScope scope(isolate);
+  Local<v8::Object> o1 = Object::New(isolate);
+  Local<v8::Object> o2 = Object::New(isolate);
+  i::Handle<i::JSObject> io1 = v8::Utils::OpenHandle(*o1);
+  i::Handle<i::JSObject> io2 = v8::Utils::OpenHandle(*o2);
+  CHECK(io1->map() == io2->map());
+  o1->SetIndexedPropertiesToExternalArrayData(
+      NULL, v8::kExternalUint32Array, 0);
+  o2->SetIndexedPropertiesToExternalArrayData(
+      NULL, v8::kExternalUint32Array, 0);
+  CHECK(io1->map() == io2->map());
+}
+
+
 THREADED_TEST(Regress137496) {
   i::FLAG_expose_gc = true;
   LocalContext context;