Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(429)

Unified Diff: src/hydrogen.cc

Issue 13728002: Add an IC for CompareNil operations (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Fix SunSpider regression Created 7 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: src/hydrogen.cc
diff --git a/src/hydrogen.cc b/src/hydrogen.cc
index e5270575e99303bfe4cf64e0b529c2c15022218a..ad74f5b8a5804afc0181c1a6e43581dbbe1a02a4 100644
--- a/src/hydrogen.cc
+++ b/src/hydrogen.cc
@@ -603,6 +603,19 @@ HConstant* HGraph::GetConstantInt32(SetOncePointer<HConstant>* pointer,
}
+HConstant* HGraph::GetConstantSmi(SetOncePointer<HConstant>* pointer,
+ int32_t value) {
+ if (!pointer->is_set()) {
+ HConstant* constant =
+ new(zone()) HConstant(Handle<Object>(Smi::FromInt(value), isolate()),
+ Representation::Tagged());
+ constant->InsertAfter(GetConstantUndefined());
+ pointer->set(constant);
+ }
+ return pointer->get();
+}
+
+
HConstant* HGraph::GetConstant0() {
return GetConstantInt32(&constant_0_, 0);
}
@@ -638,6 +651,18 @@ HConstant* HGraph::GetConstant##Name() { \
DEFINE_GET_CONSTANT(True, true, HType::Boolean(), true)
DEFINE_GET_CONSTANT(False, false, HType::Boolean(), false)
DEFINE_GET_CONSTANT(Hole, the_hole, HType::Tagged(), false)
+DEFINE_GET_CONSTANT(Null, null, HType::Tagged(), false)
+
+
+HConstant* HGraph::GetConstantSmi0() {
+ return GetConstantSmi(&constant_smi_0_, 0);
+}
+
+
+HConstant* HGraph::GetConstantSmi1() {
+ return GetConstantSmi(&constant_smi_1_, 1);
+}
+
#undef DEFINE_GET_CONSTANT
@@ -1733,6 +1758,49 @@ HValue* HGraphBuilder::BuildCloneShallowArray(HContext* context,
}
+void HGraphBuilder::BuildCompareNil(
+ HValue* value,
+ EqualityKind kind,
+ CompareNilICStub::Types types,
+ Handle<Map> map,
+ int position,
+ HIfContinuation* continuation) {
+ IfBuilder if_nil(this, position);
+ bool needs_or = false;
+ if ((types & CompareNilICStub::kCompareAgainstNull) != 0) {
+ if (needs_or) if_nil.Or();
+ if_nil.If<HCompareObjectEqAndBranch>(value, graph()->GetConstantNull());
+ needs_or = true;
+ }
+ if ((types & CompareNilICStub::kCompareAgainstUndefined) != 0) {
+ if (needs_or) if_nil.Or();
+ if_nil.If<HCompareObjectEqAndBranch>(value,
+ graph()->GetConstantUndefined());
+ needs_or = true;
+ }
+ // Handle either undetectable or monomorphic, not both.
+ ASSERT(((types & CompareNilICStub::kCompareAgainstUndetectable) == 0) ||
+ ((types & CompareNilICStub::kCompareAgainstMonomorphicMap) == 0));
+ if ((types & CompareNilICStub::kCompareAgainstUndetectable) != 0) {
+ if (needs_or) if_nil.Or();
+ if_nil.If<HIsUndetectableAndBranch>(value);
+ } else {
+ if_nil.Then();
+ if_nil.Else();
+ if ((types & CompareNilICStub::kCompareAgainstMonomorphicMap) != 0) {
+ BuildCheckNonSmi(value);
+ BuildCheckMap(value, map);
+ } else {
+ if (kind == kNonStrictEquality) {
+ if_nil.Deopt();
+ }
+ }
+ }
+
+ if_nil.CaptureContinuation(continuation);
+}
+
+
HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info,
TypeFeedbackOracle* oracle)
: HGraphBuilder(info),
@@ -10054,21 +10122,6 @@ void HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr,
}
-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,
@@ -10096,16 +10149,6 @@ static bool IsLiteralCompareTypeof(HValue* left,
}
-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,
Token::Value op,
HValue* right) {
@@ -10157,13 +10200,15 @@ void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
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);
+
+ Expression* sub_expr = NULL;
+ if (expr->IsLiteralCompareNull(&sub_expr)) {
+ HValue* sub_expr_value = sub_expr == expr->left() ? left : right;
+ return HandleLiteralCompareNil(expr, sub_expr_value, kNullValue);
}
- if (IsLiteralCompareNil(left, op, right, f->null_value(), &sub_expr)) {
- return HandleLiteralCompareNil(expr, sub_expr, kNullValue);
+ if (expr->IsLiteralCompareUndefined(&sub_expr)) {
+ HValue* sub_expr_value = sub_expr == expr->left() ? left : right;
+ return HandleLiteralCompareNil(expr, sub_expr_value, kUndefinedValue);
}
if (IsLiteralCompareBool(left, op, right)) {
HCompareObjectEqAndBranch* result =
@@ -10276,9 +10321,24 @@ void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr,
ASSERT(current_block()->HasPredecessor());
EqualityKind kind =
expr->op() == Token::EQ_STRICT ? kStrictEquality : kNonStrictEquality;
- HIsNilAndBranch* instr = new(zone()) HIsNilAndBranch(value, kind, nil);
- instr->set_position(expr->position());
- return ast_context()->ReturnControl(instr, expr->id());
+ HIfContinuation continuation;
+ TypeFeedbackId id = expr->CompareOperationFeedbackId();
+ CompareNilICStub::Types types;
+ if (kind == kStrictEquality) {
+ if (nil == kNullValue) {
+ types = CompareNilICStub::kCompareAgainstNull;
+ } else {
+ types = CompareNilICStub::kCompareAgainstUndefined;
+ }
+ } else {
+ types = static_cast<CompareNilICStub::Types>(
+ oracle()->CompareNilTypes(id));
+ if (types == 0) types = CompareNilICStub::kFullCompare;
+ }
+ Handle<Map> map_handle(oracle()->CompareNilMonomorphicReceiverType(id));
+ BuildCompareNil(value, kind, types, map_handle,
+ expr->position(), &continuation);
+ return ast_context()->ReturnContinuation(&continuation, expr->id());
}
« no previous file with comments | « src/hydrogen.h ('k') | src/hydrogen-instructions.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698