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.