Revision: 15756
Author: [email protected]
Date: Thu Jul 18 10:02:47 2013
Log: Merged r15723, r15724, r15725, r15728 into trunk branch.
Synchronize Compare-Literal behavior in FullCodegen and Hydrogen
There is no undefined Literal.
Fix LiteralCompareTypeof breakage introduced in r15723
Better fix for LiteralCompareTypeof
BUG=chromium:260345
[email protected]
Review URL: https://codereview.chromium.org/19460006
http://code.google.com/p/v8/source/detail?r=15756
Added:
/trunk/test/mjsunit/regress/regress-crbug-260345.js
Modified:
/trunk/src/ast.cc
/trunk/src/ast.h
/trunk/src/full-codegen.cc
/trunk/src/hydrogen.cc
/trunk/src/hydrogen.h
/trunk/src/version.cc
=======================================
--- /dev/null
+++ /trunk/test/mjsunit/regress/regress-crbug-260345.js Thu Jul 18 10:02:47
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());
=======================================
--- /trunk/src/ast.cc Wed Jul 10 07:57:15 2013
+++ /trunk/src/ast.cc Thu Jul 18 10:02:47 2013
@@ -71,8 +71,14 @@
}
-bool Expression::IsUndefinedLiteral() {
- return AsLiteral() != NULL && AsLiteral()->value()->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());
}
@@ -385,12 +391,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;
}
@@ -398,9 +405,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);
}
=======================================
--- /trunk/src/ast.h Mon Jul 15 01:01:13 2013
+++ /trunk/src/ast.h Thu Jul 18 10:02:47 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 bounds
Bounds bounds() { return bounds_; }
@@ -1994,7 +1994,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:
=======================================
--- /trunk/src/full-codegen.cc Mon Jul 8 01:38:06 2013
+++ /trunk/src/full-codegen.cc Thu Jul 18 10:02:47 2013
@@ -1605,7 +1605,7 @@
return true;
}
- if (expr->IsLiteralCompareUndefined(&sub_expr)) {
+ if (expr->IsLiteralCompareUndefined(&sub_expr, isolate())) {
EmitLiteralCompareNil(expr, sub_expr, kUndefinedValue);
return true;
}
=======================================
--- /trunk/src/hydrogen.cc Wed Jul 17 01:22:15 2013
+++ /trunk/src/hydrogen.cc Thu Jul 18 10:02:47 2013
@@ -8090,66 +8090,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,
@@ -8165,6 +8113,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);
@@ -8193,19 +8157,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);
@@ -8332,12 +8283,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);
=======================================
--- /trunk/src/hydrogen.h Wed Jul 17 01:22:15 2013
+++ /trunk/src/hydrogen.h Thu Jul 18 10:02:47 2013
@@ -1759,10 +1759,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,
=======================================
--- /trunk/src/version.cc Wed Jul 17 01:22:15 2013
+++ /trunk/src/version.cc Thu Jul 18 10:02:47 2013
@@ -35,7 +35,7 @@
#define MAJOR_VERSION 3
#define MINOR_VERSION 20
#define BUILD_NUMBER 6
-#define PATCH_LEVEL 0
+#define PATCH_LEVEL 1
// Use 1 for candidates and 0 otherwise.
// (Boolean macro values are not supported by all preprocessors.)
#define IS_CANDIDATE_VERSION 0
--
--
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.