The issue is that by handling strings with map/handler pairs instead of a special
authormvstanton@chromium.org <mvstanton@chromium.org>
Tue, 21 Oct 2014 13:04:51 +0000 (13:04 +0000)
committermvstanton@chromium.org <mvstanton@chromium.org>
Tue, 21 Oct 2014 13:04:51 +0000 (13:04 +0000)
version of the keyed load stub (https://code.google.com/p/v8/source/detail?r=24661),
I allowed polymorphism between string and non-string types in the IC. Before, the
IC would go generic.

Then, at crankshaft time, we special case when we only saw strings. The error
here is that crankshaft can't emit code that handles polymorphism between string
and non-string types. The choice is either to get that to happen (I don't deem
this necessary from a performance point of view, an IC with such type feedback
before would have gone generic), or simply check for the case of "polymorphic
with some string maps" and require crankshaft to go generic. I'll do the latter.

BUG=425519
LOG=N
R=jarin@chromium.org

Review URL: https://codereview.chromium.org/667923004

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

src/hydrogen.cc
test/mjsunit/regress/regress-crbug-425519.js [new file with mode: 0644]

index 663bafb..f027094 100644 (file)
@@ -7034,6 +7034,7 @@ HValue* HOptimizedGraphBuilder::HandlePolymorphicElementAccess(
   MapHandleList possible_transitioned_maps(maps->length());
   for (int i = 0; i < maps->length(); ++i) {
     Handle<Map> map = maps->at(i);
+    DCHECK(!map->IsStringMap());
     ElementsKind elements_kind = map->elements_kind();
     if (IsFastElementsKind(elements_kind) &&
         elements_kind != GetInitialFastElementsKind()) {
@@ -7197,6 +7198,19 @@ HValue* HOptimizedGraphBuilder::HandleKeyedElementAccess(
         break;
       }
     }
+  } else if (access_type == LOAD && !monomorphic &&
+             (types != NULL && !types->is_empty())) {
+    // Polymorphic loads have to go generic if any of the maps are strings.
+    // If some, but not all of the maps are strings, we should go generic
+    // because polymorphic access wants to key on ElementsKind and isn't
+    // compatible with strings.
+    for (int i = 0; i < types->length(); i++) {
+      Handle<Map> current_map = types->at(i);
+      if (current_map->IsStringMap()) {
+        force_generic = true;
+        break;
+      }
+    }
   }
 
   if (monomorphic) {
diff --git a/test/mjsunit/regress/regress-crbug-425519.js b/test/mjsunit/regress/regress-crbug-425519.js
new file mode 100644 (file)
index 0000000..d08e7b9
--- /dev/null
@@ -0,0 +1,15 @@
+// Copyright 2014 the V8 project authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+// Flags: --allow-natives-syntax
+
+function load(a, i) {
+  return a[i];
+}
+
+load([]);
+load(0);
+load("x", 0);
+%OptimizeFunctionOnNextCall(load);
+load([], 0);