Revision: 15799
Author:   [email protected]
Date:     Mon Jul 22 04:32:11 2013
Log: Merged r15267, r15610, r15723, r15724, r15725, r15728 into 3.19 branch.

HBoundsCheck shouldn't ignore Tagged input representations unconditionally

HasRealIndexedProperty doesn't work on JSGlobalProxy

Synchronize Compare-Literal behavior in FullCodegen and Hydrogen

There is no undefined Literal.

Fix LiteralCompareTypeof breakage introduced in r15723

Better fix for LiteralCompareTypeof

[email protected]
BUG=v8:2740,chromium:257748,chromium:260345

Review URL: https://codereview.chromium.org/19661003
http://code.google.com/p/v8/source/detail?r=15799

Added:
 /branches/3.19/test/mjsunit/regress/regress-crbug-260345.js
Modified:
 /branches/3.19/src/ast.cc
 /branches/3.19/src/ast.h
 /branches/3.19/src/full-codegen.cc
 /branches/3.19/src/hydrogen-instructions.cc
 /branches/3.19/src/hydrogen.cc
 /branches/3.19/src/hydrogen.h
 /branches/3.19/src/objects.cc
 /branches/3.19/src/version.cc
 /branches/3.19/test/cctest/test-api.cc

=======================================
--- /dev/null
+++ /branches/3.19/test/mjsunit/regress/regress-crbug-260345.js Mon Jul 22 04:32:11 2013
@@ -0,0 +1,59 @@
+// Copyright 2013 the V8 project authors. All rights reserved.
+// Redistribution and use in source and binary forms, with or without
+// modification, are permitted provided that the following conditions are
+// met:
+//
+//     * Redistributions of source code must retain the above copyright
+//       notice, this list of conditions and the following disclaimer.
+//     * Redistributions in binary form must reproduce the above
+//       copyright notice, this list of conditions and the following
+//       disclaimer in the documentation and/or other materials provided
+//       with the distribution.
+//     * Neither the name of Google Inc. nor the names of its
+//       contributors may be used to endorse or promote products derived
+//       from this software without specific prior written permission.
+//
+// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+
+var steps = 100000;
+var undefined_values = [undefined, "go on"];
+var null_values = [null, "go on"];
+
+function get_undefined_object(i) {
+  return undefined_values[(i / steps) | 0];
+}
+
+function test_undefined() {
+  var objects = 0;
+  for (var i = 0; i < 2 * steps; i++) {
+    undefined == get_undefined_object(i) && objects++;
+  }
+  return objects;
+}
+
+assertEquals(steps, test_undefined());
+
+
+function get_null_object(i) {
+  return null_values[(i / steps) | 0];
+}
+
+function test_null() {
+  var objects = 0;
+  for (var i = 0; i < 2 * steps; i++) {
+    null == get_null_object(i) && objects++;
+  }
+  return objects;
+}
+
+assertEquals(steps, test_null());
=======================================
--- /branches/3.19/src/ast.cc   Tue Jun 18 04:54:54 2013
+++ /branches/3.19/src/ast.cc   Mon Jul 22 04:32:11 2013
@@ -71,8 +71,14 @@
 }


-bool Expression::IsUndefinedLiteral() {
-  return AsLiteral() != NULL && AsLiteral()->handle()->IsUndefined();
+bool Expression::IsUndefinedLiteral(Isolate* isolate) {
+  VariableProxy* var_proxy = AsVariableProxy();
+  if (var_proxy == NULL) return false;
+  Variable* var = var_proxy->var();
+  // The global identifier "undefined" is immutable. Everything
+  // else could be reassigned.
+  return var != NULL && var->location() == Variable::UNALLOCATED &&
+         var_proxy->name()->Equals(isolate->heap()->undefined_string());
 }


@@ -364,12 +370,13 @@
 static bool MatchLiteralCompareUndefined(Expression* left,
                                          Token::Value op,
                                          Expression* right,
-                                         Expression** expr) {
+                                         Expression** expr,
+                                         Isolate* isolate) {
   if (IsVoidOfLiteral(left) && Token::IsEqualityOp(op)) {
     *expr = right;
     return true;
   }
-  if (left->IsUndefinedLiteral() && Token::IsEqualityOp(op)) {
+  if (left->IsUndefinedLiteral(isolate) && Token::IsEqualityOp(op)) {
     *expr = right;
     return true;
   }
@@ -377,9 +384,10 @@
 }


-bool CompareOperation::IsLiteralCompareUndefined(Expression** expr) {
-  return MatchLiteralCompareUndefined(left_, op_, right_, expr) ||
-      MatchLiteralCompareUndefined(right_, op_, left_, expr);
+bool CompareOperation::IsLiteralCompareUndefined(
+    Expression** expr, Isolate* isolate) {
+  return MatchLiteralCompareUndefined(left_, op_, right_, expr, isolate) ||
+      MatchLiteralCompareUndefined(right_, op_, left_, expr, isolate);
 }


=======================================
--- /branches/3.19/src/ast.h    Tue Jun 18 04:54:54 2013
+++ /branches/3.19/src/ast.h    Mon Jul 22 04:32:11 2013
@@ -353,8 +353,8 @@
   // True iff the expression is the null literal.
   bool IsNullLiteral();

-  // True iff the expression is the undefined literal.
-  bool IsUndefinedLiteral();
+  // True if we can prove that the expression is the undefined literal.
+  bool IsUndefinedLiteral(Isolate* isolate);

   // Expression type
   Handle<Type> type() { return type_; }
@@ -2002,7 +2002,7 @@

   // Match special cases.
   bool IsLiteralCompareTypeof(Expression** expr, Handle<String>* check);
-  bool IsLiteralCompareUndefined(Expression** expr);
+  bool IsLiteralCompareUndefined(Expression** expr, Isolate* isolate);
   bool IsLiteralCompareNull(Expression** expr);

  protected:
=======================================
--- /branches/3.19/src/full-codegen.cc  Wed Jun 12 15:31:22 2013
+++ /branches/3.19/src/full-codegen.cc  Mon Jul 22 04:32:11 2013
@@ -1597,7 +1597,7 @@
     return true;
   }

-  if (expr->IsLiteralCompareUndefined(&sub_expr)) {
+  if (expr->IsLiteralCompareUndefined(&sub_expr, isolate())) {
     EmitLiteralCompareNil(expr, sub_expr, kUndefinedValue);
     return true;
   }
=======================================
--- /branches/3.19/src/hydrogen-instructions.cc Mon Jun 24 04:29:10 2013
+++ /branches/3.19/src/hydrogen-instructions.cc Mon Jul 22 04:32:11 2013
@@ -1155,8 +1155,12 @@
   HValue* actual_length = length()->ActualValue();
   Representation index_rep = actual_index->representation();
   Representation length_rep = actual_length->representation();
-  if (index_rep.IsTagged()) index_rep = Representation::Smi();
-  if (length_rep.IsTagged()) length_rep = Representation::Smi();
+  if (index_rep.IsTagged() && actual_index->type().IsSmi()) {
+    index_rep = Representation::Smi();
+  }
+  if (length_rep.IsTagged() && actual_length->type().IsSmi()) {
+    length_rep = Representation::Smi();
+  }
   Representation r = index_rep.generalize(length_rep);
   if (r.is_more_general_than(Representation::Integer32())) {
     r = Representation::Integer32();
=======================================
--- /branches/3.19/src/hydrogen.cc      Thu Jun 20 09:20:19 2013
+++ /branches/3.19/src/hydrogen.cc      Mon Jul 22 04:32:11 2013
@@ -9746,66 +9746,14 @@


void HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr, - HTypeof* typeof_expr, + Expression* sub_expr, Handle<String> check) { - // Note: The HTypeof itself is removed during canonicalization, if possible.
-  HValue* value = typeof_expr->value();
+  CHECK_ALIVE(VisitForTypeOf(sub_expr));
+  HValue* value = Pop();
   HTypeofIsAndBranch* instr = new(zone()) HTypeofIsAndBranch(value, check);
   instr->set_position(expr->position());
   return ast_context()->ReturnControl(instr, expr->id());
 }
-
-
-static bool MatchLiteralCompareNil(HValue* left,
-                                   Token::Value op,
-                                   HValue* right,
-                                   Handle<Object> nil,
-                                   HValue** expr) {
-  if (left->IsConstant() &&
-      HConstant::cast(left)->handle().is_identical_to(nil) &&
-      Token::IsEqualityOp(op)) {
-    *expr = right;
-    return true;
-  }
-  return false;
-}
-
-
-static bool MatchLiteralCompareTypeof(HValue* left,
-                                      Token::Value op,
-                                      HValue* right,
-                                      HTypeof** typeof_expr,
-                                      Handle<String>* check) {
-  if (left->IsTypeof() &&
-      Token::IsEqualityOp(op) &&
-      right->IsConstant() &&
-      HConstant::cast(right)->handle()->IsString()) {
-    *typeof_expr = HTypeof::cast(left);
-    *check = Handle<String>::cast(HConstant::cast(right)->handle());
-    return true;
-  }
-  return false;
-}
-
-
-static bool IsLiteralCompareTypeof(HValue* left,
-                                   Token::Value op,
-                                   HValue* right,
-                                   HTypeof** typeof_expr,
-                                   Handle<String>* check) {
-  return MatchLiteralCompareTypeof(left, op, right, typeof_expr, check) ||
-      MatchLiteralCompareTypeof(right, op, left, typeof_expr, check);
-}
-
-
-static bool IsLiteralCompareNil(HValue* left,
-                                Token::Value op,
-                                HValue* right,
-                                Handle<Object> nil,
-                                HValue** expr) {
-  return MatchLiteralCompareNil(left, op, right, nil, expr) ||
-      MatchLiteralCompareNil(right, op, left, nil, expr);
-}


 static bool IsLiteralCompareBool(HValue* left,
@@ -9821,6 +9769,22 @@
   ASSERT(!HasStackOverflow());
   ASSERT(current_block() != NULL);
   ASSERT(current_block()->HasPredecessor());
+
+  // Check for a few fast cases. The AST visiting behavior must be in sync
+  // with the full codegen: We don't push both left and right values onto
+  // the expression stack when one side is a special-case literal.
+  Expression* sub_expr = NULL;
+  Handle<String> check;
+  if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) {
+    return HandleLiteralCompareTypeof(expr, sub_expr, check);
+  }
+  if (expr->IsLiteralCompareUndefined(&sub_expr, isolate())) {
+    return HandleLiteralCompareNil(expr, sub_expr, kUndefinedValue);
+  }
+  if (expr->IsLiteralCompareNull(&sub_expr)) {
+    return HandleLiteralCompareNil(expr, sub_expr, kNullValue);
+  }
+
   if (IsClassOfTest(expr)) {
     CallRuntime* call = expr->left()->AsCallRuntime();
     ASSERT(call->arguments()->length() == 1);
@@ -9855,19 +9819,6 @@
   HValue* left = Pop();
   Token::Value op = expr->op();

-  HTypeof* typeof_expr = NULL;
-  Handle<String> check;
-  if (IsLiteralCompareTypeof(left, op, right, &typeof_expr, &check)) {
-    return HandleLiteralCompareTypeof(expr, typeof_expr, check);
-  }
-  HValue* sub_expr = NULL;
-  Factory* f = isolate()->factory();
- if (IsLiteralCompareNil(left, op, right, f->undefined_value(), &sub_expr)) {
-    return HandleLiteralCompareNil(expr, sub_expr, kUndefinedValue);
-  }
-  if (IsLiteralCompareNil(left, op, right, f->null_value(), &sub_expr)) {
-    return HandleLiteralCompareNil(expr, sub_expr, kNullValue);
-  }
   if (IsLiteralCompareBool(left, op, right)) {
     HCompareObjectEqAndBranch* result =
         new(zone()) HCompareObjectEqAndBranch(left, right);
@@ -9977,12 +9928,14 @@


void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr,
-                                                     HValue* value,
+                                                     Expression* sub_expr,
                                                      NilValue nil) {
   ASSERT(!HasStackOverflow());
   ASSERT(current_block() != NULL);
   ASSERT(current_block()->HasPredecessor());
   ASSERT(expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT);
+  CHECK_ALIVE(VisitForValue(sub_expr));
+  HValue* value = Pop();
   HIfContinuation continuation;
   if (expr->op() == Token::EQ_STRICT) {
     IfBuilder if_nil(this);
=======================================
--- /branches/3.19/src/hydrogen.h       Thu Jun 20 09:20:19 2013
+++ /branches/3.19/src/hydrogen.h       Mon Jul 22 04:32:11 2013
@@ -1721,10 +1721,10 @@
                                   SmallMapList* types,
                                   Handle<String> name);
   void HandleLiteralCompareTypeof(CompareOperation* expr,
-                                  HTypeof* typeof_expr,
+                                  Expression* sub_expr,
                                   Handle<String> check);
   void HandleLiteralCompareNil(CompareOperation* expr,
-                               HValue* value,
+                               Expression* sub_expr,
                                NilValue nil);

   HInstruction* BuildStringCharCodeAt(HValue* context,
=======================================
--- /branches/3.19/src/objects.cc       Tue Jun 18 04:54:54 2013
+++ /branches/3.19/src/objects.cc       Mon Jul 22 04:32:11 2013
@@ -3242,7 +3242,6 @@
     Object* proto = GetPrototype();
     if (proto->IsNull()) return result->NotFound();
     ASSERT(proto->IsJSGlobalObject());
-    // A GlobalProxy's prototype should always be a proper JSObject.
return JSObject::cast(proto)->LocalLookupRealNamedProperty(name, result);
   }

@@ -12838,6 +12837,13 @@
       return false;
     }
   }
+
+  if (IsJSGlobalProxy()) {
+    Object* proto = GetPrototype();
+    if (proto->IsNull()) return false;
+    ASSERT(proto->IsJSGlobalObject());
+    return JSObject::cast(proto)->HasRealElementProperty(isolate, index);
+  }

return GetElementAttributeWithoutInterceptor(this, index, false) != ABSENT;
 }
=======================================
--- /branches/3.19/src/version.cc       Fri Jul 19 01:56:03 2013
+++ /branches/3.19/src/version.cc       Mon Jul 22 04:32:11 2013
@@ -35,7 +35,7 @@
 #define MAJOR_VERSION     3
 #define MINOR_VERSION     19
 #define BUILD_NUMBER      18
-#define PATCH_LEVEL       14
+#define PATCH_LEVEL       15
 // Use 1 for candidates and 0 otherwise.
 // (Boolean macro values are not supported by all preprocessors.)
 #define IS_CANDIDATE_VERSION 0
=======================================
--- /branches/3.19/test/cctest/test-api.cc      Fri Jul 19 01:56:03 2013
+++ /branches/3.19/test/cctest/test-api.cc      Mon Jul 22 04:32:11 2013
@@ -2433,6 +2433,16 @@
   global->SetInternalField(0, v8_num(17));
   CHECK_EQ(17, global->GetInternalField(0)->Int32Value());
 }
+
+
+THREADED_TEST(GlobalObjectHasRealIndexedProperty) {
+  LocalContext env;
+  v8::HandleScope scope(v8::Isolate::GetCurrent());
+
+  v8::Local<v8::Object> global = env->Global();
+  global->Set(0, v8::String::New("value"));
+  CHECK(global->HasRealIndexedProperty(0));
+}


 static void CheckAlignedPointerInInternalField(Handle<v8::Object> obj,

--
--
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/groups/opt_out.


Reply via email to