| OLD | NEW | 
|      1 // Copyright 2013 the V8 project authors. All rights reserved. |      1 // Copyright 2013 the V8 project authors. All rights reserved. | 
|      2 // Redistribution and use in source and binary forms, with or without |      2 // Redistribution and use in source and binary forms, with or without | 
|      3 // modification, are permitted provided that the following conditions are |      3 // modification, are permitted provided that the following conditions are | 
|      4 // met: |      4 // met: | 
|      5 // |      5 // | 
|      6 //     * Redistributions of source code must retain the above copyright |      6 //     * Redistributions of source code must retain the above copyright | 
|      7 //       notice, this list of conditions and the following disclaimer. |      7 //       notice, this list of conditions and the following disclaimer. | 
|      8 //     * Redistributions in binary form must reproduce the above |      8 //     * Redistributions in binary form must reproduce the above | 
|      9 //       copyright notice, this list of conditions and the following |      9 //       copyright notice, this list of conditions and the following | 
|     10 //       disclaimer in the documentation and/or other materials provided |     10 //       disclaimer in the documentation and/or other materials provided | 
| (...skipping 8072 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   8083   CHECK_ALIVE(VisitForValue(expr->right())); |   8083   CHECK_ALIVE(VisitForValue(expr->right())); | 
|   8084   HValue* right = Pop(); |   8084   HValue* right = Pop(); | 
|   8085   HValue* left = Pop(); |   8085   HValue* left = Pop(); | 
|   8086   HInstruction* instr = BuildBinaryOperation(expr, left, right); |   8086   HInstruction* instr = BuildBinaryOperation(expr, left, right); | 
|   8087   instr->set_position(expr->position()); |   8087   instr->set_position(expr->position()); | 
|   8088   return ast_context()->ReturnInstruction(instr, expr->id()); |   8088   return ast_context()->ReturnInstruction(instr, expr->id()); | 
|   8089 } |   8089 } | 
|   8090  |   8090  | 
|   8091  |   8091  | 
|   8092 void HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr, |   8092 void HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr, | 
|   8093                                                         HTypeof* typeof_expr, |   8093                                                         Expression* sub_expr, | 
|   8094                                                         Handle<String> check) { |   8094                                                         Handle<String> check) { | 
|   8095   // Note: The HTypeof itself is removed during canonicalization, if possible. |   8095   CHECK_ALIVE(VisitForTypeOf(sub_expr)); | 
|   8096   HValue* value = typeof_expr->value(); |   8096   HValue* value = Pop(); | 
|   8097   HTypeofIsAndBranch* instr = new(zone()) HTypeofIsAndBranch(value, check); |   8097   HTypeofIsAndBranch* instr = new(zone()) HTypeofIsAndBranch(value, check); | 
|   8098   instr->set_position(expr->position()); |   8098   instr->set_position(expr->position()); | 
|   8099   return ast_context()->ReturnControl(instr, expr->id()); |   8099   return ast_context()->ReturnControl(instr, expr->id()); | 
|   8100 } |   8100 } | 
|   8101  |   8101  | 
|   8102  |   8102  | 
|   8103 static bool MatchLiteralCompareNil(HValue* left, |  | 
|   8104                                    Token::Value op, |  | 
|   8105                                    HValue* right, |  | 
|   8106                                    Handle<Object> nil, |  | 
|   8107                                    HValue** expr) { |  | 
|   8108   if (left->IsConstant() && |  | 
|   8109       HConstant::cast(left)->handle().is_identical_to(nil) && |  | 
|   8110       Token::IsEqualityOp(op)) { |  | 
|   8111     *expr = right; |  | 
|   8112     return true; |  | 
|   8113   } |  | 
|   8114   return false; |  | 
|   8115 } |  | 
|   8116  |  | 
|   8117  |  | 
|   8118 static bool MatchLiteralCompareTypeof(HValue* left, |  | 
|   8119                                       Token::Value op, |  | 
|   8120                                       HValue* right, |  | 
|   8121                                       HTypeof** typeof_expr, |  | 
|   8122                                       Handle<String>* check) { |  | 
|   8123   if (left->IsTypeof() && |  | 
|   8124       Token::IsEqualityOp(op) && |  | 
|   8125       right->IsConstant() && |  | 
|   8126       HConstant::cast(right)->handle()->IsString()) { |  | 
|   8127     *typeof_expr = HTypeof::cast(left); |  | 
|   8128     *check = Handle<String>::cast(HConstant::cast(right)->handle()); |  | 
|   8129     return true; |  | 
|   8130   } |  | 
|   8131   return false; |  | 
|   8132 } |  | 
|   8133  |  | 
|   8134  |  | 
|   8135 static bool IsLiteralCompareTypeof(HValue* left, |  | 
|   8136                                    Token::Value op, |  | 
|   8137                                    HValue* right, |  | 
|   8138                                    HTypeof** typeof_expr, |  | 
|   8139                                    Handle<String>* check) { |  | 
|   8140   return MatchLiteralCompareTypeof(left, op, right, typeof_expr, check) || |  | 
|   8141       MatchLiteralCompareTypeof(right, op, left, typeof_expr, check); |  | 
|   8142 } |  | 
|   8143  |  | 
|   8144  |  | 
|   8145 static bool IsLiteralCompareNil(HValue* left, |  | 
|   8146                                 Token::Value op, |  | 
|   8147                                 HValue* right, |  | 
|   8148                                 Handle<Object> nil, |  | 
|   8149                                 HValue** expr) { |  | 
|   8150   return MatchLiteralCompareNil(left, op, right, nil, expr) || |  | 
|   8151       MatchLiteralCompareNil(right, op, left, nil, expr); |  | 
|   8152 } |  | 
|   8153  |  | 
|   8154  |  | 
|   8155 static bool IsLiteralCompareBool(HValue* left, |   8103 static bool IsLiteralCompareBool(HValue* left, | 
|   8156                                  Token::Value op, |   8104                                  Token::Value op, | 
|   8157                                  HValue* right) { |   8105                                  HValue* right) { | 
|   8158   return op == Token::EQ_STRICT && |   8106   return op == Token::EQ_STRICT && | 
|   8159       ((left->IsConstant() && HConstant::cast(left)->handle()->IsBoolean()) || |   8107       ((left->IsConstant() && HConstant::cast(left)->handle()->IsBoolean()) || | 
|   8160        (right->IsConstant() && HConstant::cast(right)->handle()->IsBoolean())); |   8108        (right->IsConstant() && HConstant::cast(right)->handle()->IsBoolean())); | 
|   8161 } |   8109 } | 
|   8162  |   8110  | 
|   8163  |   8111  | 
|   8164 void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) { |   8112 void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) { | 
|   8165   ASSERT(!HasStackOverflow()); |   8113   ASSERT(!HasStackOverflow()); | 
|   8166   ASSERT(current_block() != NULL); |   8114   ASSERT(current_block() != NULL); | 
|   8167   ASSERT(current_block()->HasPredecessor()); |   8115   ASSERT(current_block()->HasPredecessor()); | 
 |   8116  | 
 |   8117   // Check for a few fast cases. The AST visiting behavior must be in sync | 
 |   8118   // with the full codegen: We don't push both left and right values onto | 
 |   8119   // the expression stack when one side is a special-case literal. | 
 |   8120   Expression* sub_expr = NULL; | 
 |   8121   Handle<String> check; | 
 |   8122   if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) { | 
 |   8123     return HandleLiteralCompareTypeof(expr, sub_expr, check); | 
 |   8124   } | 
 |   8125   if (expr->IsLiteralCompareUndefined(&sub_expr, isolate())) { | 
 |   8126     return HandleLiteralCompareNil(expr, sub_expr, kUndefinedValue); | 
 |   8127   } | 
 |   8128   if (expr->IsLiteralCompareNull(&sub_expr)) { | 
 |   8129     return HandleLiteralCompareNil(expr, sub_expr, kNullValue); | 
 |   8130   } | 
 |   8131  | 
|   8168   if (IsClassOfTest(expr)) { |   8132   if (IsClassOfTest(expr)) { | 
|   8169     CallRuntime* call = expr->left()->AsCallRuntime(); |   8133     CallRuntime* call = expr->left()->AsCallRuntime(); | 
|   8170     ASSERT(call->arguments()->length() == 1); |   8134     ASSERT(call->arguments()->length() == 1); | 
|   8171     CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); |   8135     CHECK_ALIVE(VisitForValue(call->arguments()->at(0))); | 
|   8172     HValue* value = Pop(); |   8136     HValue* value = Pop(); | 
|   8173     Literal* literal = expr->right()->AsLiteral(); |   8137     Literal* literal = expr->right()->AsLiteral(); | 
|   8174     Handle<String> rhs = Handle<String>::cast(literal->value()); |   8138     Handle<String> rhs = Handle<String>::cast(literal->value()); | 
|   8175     HClassOfTestAndBranch* instr = |   8139     HClassOfTestAndBranch* instr = | 
|   8176         new(zone()) HClassOfTestAndBranch(value, rhs); |   8140         new(zone()) HClassOfTestAndBranch(value, rhs); | 
|   8177     instr->set_position(expr->position()); |   8141     instr->set_position(expr->position()); | 
|   8178     return ast_context()->ReturnControl(instr, expr->id()); |   8142     return ast_context()->ReturnControl(instr, expr->id()); | 
|   8179   } |   8143   } | 
|   8180  |   8144  | 
|   8181   Handle<Type> left_type = expr->left()->bounds().lower; |   8145   Handle<Type> left_type = expr->left()->bounds().lower; | 
|   8182   Handle<Type> right_type = expr->right()->bounds().lower; |   8146   Handle<Type> right_type = expr->right()->bounds().lower; | 
|   8183   Handle<Type> combined_type = expr->combined_type(); |   8147   Handle<Type> combined_type = expr->combined_type(); | 
|   8184   Representation combined_rep = Representation::FromType(combined_type); |   8148   Representation combined_rep = Representation::FromType(combined_type); | 
|   8185   Representation left_rep = Representation::FromType(left_type); |   8149   Representation left_rep = Representation::FromType(left_type); | 
|   8186   Representation right_rep = Representation::FromType(right_type); |   8150   Representation right_rep = Representation::FromType(right_type); | 
|   8187  |   8151  | 
|   8188   CHECK_ALIVE(VisitForValue(expr->left())); |   8152   CHECK_ALIVE(VisitForValue(expr->left())); | 
|   8189   CHECK_ALIVE(VisitForValue(expr->right())); |   8153   CHECK_ALIVE(VisitForValue(expr->right())); | 
|   8190  |   8154  | 
|   8191   HValue* context = environment()->LookupContext(); |   8155   HValue* context = environment()->LookupContext(); | 
|   8192   HValue* right = Pop(); |   8156   HValue* right = Pop(); | 
|   8193   HValue* left = Pop(); |   8157   HValue* left = Pop(); | 
|   8194   Token::Value op = expr->op(); |   8158   Token::Value op = expr->op(); | 
|   8195  |   8159  | 
|   8196   HTypeof* typeof_expr = NULL; |  | 
|   8197   Handle<String> check; |  | 
|   8198   if (IsLiteralCompareTypeof(left, op, right, &typeof_expr, &check)) { |  | 
|   8199     return HandleLiteralCompareTypeof(expr, typeof_expr, check); |  | 
|   8200   } |  | 
|   8201   HValue* sub_expr = NULL; |  | 
|   8202   Factory* f = isolate()->factory(); |  | 
|   8203   if (IsLiteralCompareNil(left, op, right, f->undefined_value(), &sub_expr)) { |  | 
|   8204     return HandleLiteralCompareNil(expr, sub_expr, kUndefinedValue); |  | 
|   8205   } |  | 
|   8206   if (IsLiteralCompareNil(left, op, right, f->null_value(), &sub_expr)) { |  | 
|   8207     return HandleLiteralCompareNil(expr, sub_expr, kNullValue); |  | 
|   8208   } |  | 
|   8209   if (IsLiteralCompareBool(left, op, right)) { |   8160   if (IsLiteralCompareBool(left, op, right)) { | 
|   8210     HCompareObjectEqAndBranch* result = |   8161     HCompareObjectEqAndBranch* result = | 
|   8211         new(zone()) HCompareObjectEqAndBranch(left, right); |   8162         new(zone()) HCompareObjectEqAndBranch(left, right); | 
|   8212     result->set_position(expr->position()); |   8163     result->set_position(expr->position()); | 
|   8213     return ast_context()->ReturnControl(result, expr->id()); |   8164     return ast_context()->ReturnControl(result, expr->id()); | 
|   8214   } |   8165   } | 
|   8215  |   8166  | 
|   8216   if (op == Token::INSTANCEOF) { |   8167   if (op == Token::INSTANCEOF) { | 
|   8217     // Check to see if the rhs of the instanceof is a global function not |   8168     // Check to see if the rhs of the instanceof is a global function not | 
|   8218     // residing in new space. If it is we assume that the function will stay the |   8169     // residing in new space. If it is we assume that the function will stay the | 
| (...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   8325           new(zone()) HCompareNumericAndBranch(left, right, op); |   8276           new(zone()) HCompareNumericAndBranch(left, right, op); | 
|   8326       result->set_observed_input_representation(left_rep, right_rep); |   8277       result->set_observed_input_representation(left_rep, right_rep); | 
|   8327       result->set_position(expr->position()); |   8278       result->set_position(expr->position()); | 
|   8328       return ast_context()->ReturnControl(result, expr->id()); |   8279       return ast_context()->ReturnControl(result, expr->id()); | 
|   8329     } |   8280     } | 
|   8330   } |   8281   } | 
|   8331 } |   8282 } | 
|   8332  |   8283  | 
|   8333  |   8284  | 
|   8334 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, |   8285 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, | 
|   8335                                                      HValue* value, |   8286                                                      Expression* sub_expr, | 
|   8336                                                      NilValue nil) { |   8287                                                      NilValue nil) { | 
|   8337   ASSERT(!HasStackOverflow()); |   8288   ASSERT(!HasStackOverflow()); | 
|   8338   ASSERT(current_block() != NULL); |   8289   ASSERT(current_block() != NULL); | 
|   8339   ASSERT(current_block()->HasPredecessor()); |   8290   ASSERT(current_block()->HasPredecessor()); | 
|   8340   ASSERT(expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT); |   8291   ASSERT(expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT); | 
 |   8292   CHECK_ALIVE(VisitForValue(sub_expr)); | 
 |   8293   HValue* value = Pop(); | 
|   8341   HIfContinuation continuation; |   8294   HIfContinuation continuation; | 
|   8342   if (expr->op() == Token::EQ_STRICT) { |   8295   if (expr->op() == Token::EQ_STRICT) { | 
|   8343     IfBuilder if_nil(this); |   8296     IfBuilder if_nil(this); | 
|   8344     if_nil.If<HCompareObjectEqAndBranch>( |   8297     if_nil.If<HCompareObjectEqAndBranch>( | 
|   8345         value, (nil == kNullValue) ? graph()->GetConstantNull() |   8298         value, (nil == kNullValue) ? graph()->GetConstantNull() | 
|   8346                                    : graph()->GetConstantUndefined()); |   8299                                    : graph()->GetConstantUndefined()); | 
|   8347     if_nil.Then(); |   8300     if_nil.Then(); | 
|   8348     if_nil.Else(); |   8301     if_nil.Else(); | 
|   8349     if_nil.CaptureContinuation(&continuation); |   8302     if_nil.CaptureContinuation(&continuation); | 
|   8350     return ast_context()->ReturnContinuation(&continuation, expr->id()); |   8303     return ast_context()->ReturnContinuation(&continuation, expr->id()); | 
| (...skipping 1643 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   9994   if (ShouldProduceTraceOutput()) { |   9947   if (ShouldProduceTraceOutput()) { | 
|   9995     isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |   9948     isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 
|   9996   } |   9949   } | 
|   9997  |   9950  | 
|   9998 #ifdef DEBUG |   9951 #ifdef DEBUG | 
|   9999   graph_->Verify(false);  // No full verify. |   9952   graph_->Verify(false);  // No full verify. | 
|  10000 #endif |   9953 #endif | 
|  10001 } |   9954 } | 
|  10002  |   9955  | 
|  10003 } }  // namespace v8::internal |   9956 } }  // namespace v8::internal | 
| OLD | NEW |