| OLD | NEW |
| 1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 561 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 572 if (!pointer->is_set()) { | 572 if (!pointer->is_set()) { |
| 573 HConstant* constant = new(zone()) HConstant(Handle<Object>(value), | 573 HConstant* constant = new(zone()) HConstant(Handle<Object>(value), |
| 574 Representation::Tagged()); | 574 Representation::Tagged()); |
| 575 constant->InsertAfter(GetConstantUndefined()); | 575 constant->InsertAfter(GetConstantUndefined()); |
| 576 pointer->set(constant); | 576 pointer->set(constant); |
| 577 } | 577 } |
| 578 return pointer->get(); | 578 return pointer->get(); |
| 579 } | 579 } |
| 580 | 580 |
| 581 | 581 |
| 582 HConstant* HGraph::GetConstantInt32(SetOncePointer<HConstant>* pointer, |
| 583 int32_t value) { |
| 584 if (!pointer->is_set()) { |
| 585 HConstant* constant = new(zone()) HConstant(value, |
| 586 Representation::Integer32(), |
| 587 Handle<Object>::null()); |
| 588 constant->InsertAfter(GetConstantUndefined()); |
| 589 pointer->set(constant); |
| 590 } |
| 591 return pointer->get(); |
| 592 } |
| 593 |
| 594 |
| 582 HConstant* HGraph::GetConstant1() { | 595 HConstant* HGraph::GetConstant1() { |
| 583 return GetConstant(&constant_1_, Smi::FromInt(1)); | 596 return GetConstantInt32(&constant_1_, 1); |
| 584 } | 597 } |
| 585 | 598 |
| 586 | 599 |
| 587 HConstant* HGraph::GetConstantMinus1() { | 600 HConstant* HGraph::GetConstantMinus1() { |
| 588 return GetConstant(&constant_minus1_, Smi::FromInt(-1)); | 601 return GetConstantInt32(&constant_minus1_, -1); |
| 589 } | 602 } |
| 590 | 603 |
| 591 | 604 |
| 592 HConstant* HGraph::GetConstantTrue() { | 605 HConstant* HGraph::GetConstantTrue() { |
| 593 return GetConstant(&constant_true_, isolate()->heap()->true_value()); | 606 return GetConstant(&constant_true_, isolate()->heap()->true_value()); |
| 594 } | 607 } |
| 595 | 608 |
| 596 | 609 |
| 597 HConstant* HGraph::GetConstantFalse() { | 610 HConstant* HGraph::GetConstantFalse() { |
| 598 return GetConstant(&constant_false_, isolate()->heap()->false_value()); | 611 return GetConstant(&constant_false_, isolate()->heap()->false_value()); |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 709 PrintF("Not enough virtual registers (regalloc).\n"); | 722 PrintF("Not enough virtual registers (regalloc).\n"); |
| 710 } | 723 } |
| 711 return Handle<Code>::null(); | 724 return Handle<Code>::null(); |
| 712 } | 725 } |
| 713 | 726 |
| 714 MacroAssembler assembler(isolate(), NULL, 0); | 727 MacroAssembler assembler(isolate(), NULL, 0); |
| 715 LCodeGen generator(chunk, &assembler, info()); | 728 LCodeGen generator(chunk, &assembler, info()); |
| 716 | 729 |
| 717 chunk->MarkEmptyBlocks(); | 730 chunk->MarkEmptyBlocks(); |
| 718 | 731 |
| 732 EnsureConstantsHaveHandles(); |
| 733 |
| 719 if (generator.GenerateCode()) { | 734 if (generator.GenerateCode()) { |
| 720 if (FLAG_trace_codegen) { | 735 if (FLAG_trace_codegen) { |
| 721 PrintF("Crankshaft Compiler - "); | 736 PrintF("Crankshaft Compiler - "); |
| 722 } | 737 } |
| 723 CodeGenerator::MakeCodePrologue(info()); | 738 CodeGenerator::MakeCodePrologue(info()); |
| 724 Code::Flags flags = Code::ComputeFlags(Code::OPTIMIZED_FUNCTION); | 739 Code::Flags flags = Code::ComputeFlags(Code::OPTIMIZED_FUNCTION); |
| 725 Handle<Code> code = | 740 Handle<Code> code = |
| 726 CodeGenerator::MakeCodeEpilogue(&assembler, flags, info()); | 741 CodeGenerator::MakeCodeEpilogue(&assembler, flags, info()); |
| 727 generator.FinishCode(code); | 742 generator.FinishCode(code); |
| 728 CodeGenerator::PrintCode(code, info()); | 743 CodeGenerator::PrintCode(code, info()); |
| (...skipping 2315 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3044 for (int i = 0; i < exprs->length(); ++i) { | 3059 for (int i = 0; i < exprs->length(); ++i) { |
| 3045 CHECK_ALIVE(VisitForValue(exprs->at(i))); | 3060 CHECK_ALIVE(VisitForValue(exprs->at(i))); |
| 3046 } | 3061 } |
| 3047 } | 3062 } |
| 3048 | 3063 |
| 3049 | 3064 |
| 3050 HGraph* HGraphBuilder::CreateGraph() { | 3065 HGraph* HGraphBuilder::CreateGraph() { |
| 3051 graph_ = new(zone()) HGraph(info()); | 3066 graph_ = new(zone()) HGraph(info()); |
| 3052 if (FLAG_hydrogen_stats) HStatistics::Instance()->Initialize(info()); | 3067 if (FLAG_hydrogen_stats) HStatistics::Instance()->Initialize(info()); |
| 3053 | 3068 |
| 3069 Factory* f = info()->isolate()->factory(); |
| 3070 constant_undefined_ = new(zone()) HConstant(f->undefined_value(), |
| 3071 Representation::Tagged()); |
| 3072 constant_null_ = new(zone()) HConstant(f->null_value(), |
| 3073 Representation::Tagged()); |
| 3074 |
| 3054 { | 3075 { |
| 3055 HPhase phase("H_Block building"); | 3076 HPhase phase("H_Block building"); |
| 3056 CompilationHandleScope handle_scope(info()); | 3077 CompilationHandleScope handle_scope(info()); |
| 3057 current_block_ = graph()->entry_block(); | 3078 current_block_ = graph()->entry_block(); |
| 3058 | 3079 |
| 3059 Scope* scope = info()->scope(); | 3080 Scope* scope = info()->scope(); |
| 3060 if (scope->HasIllegalRedeclaration()) { | 3081 if (scope->HasIllegalRedeclaration()) { |
| 3061 Bailout("function with illegal redeclaration"); | 3082 Bailout("function with illegal redeclaration"); |
| 3062 return NULL; | 3083 return NULL; |
| 3063 } | 3084 } |
| (...skipping 4719 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7783 instr = HShl::NewHShl(zone(), context, left, right); | 7804 instr = HShl::NewHShl(zone(), context, left, right); |
| 7784 break; | 7805 break; |
| 7785 default: | 7806 default: |
| 7786 UNREACHABLE(); | 7807 UNREACHABLE(); |
| 7787 } | 7808 } |
| 7788 | 7809 |
| 7789 // If we hit an uninitialized binary op stub we will get type info | 7810 // If we hit an uninitialized binary op stub we will get type info |
| 7790 // for a smi operation. If one of the operands is a constant string | 7811 // for a smi operation. If one of the operands is a constant string |
| 7791 // do not generate code assuming it is a smi operation. | 7812 // do not generate code assuming it is a smi operation. |
| 7792 if (info.IsSmi() && | 7813 if (info.IsSmi() && |
| 7793 ((left->IsConstant() && HConstant::cast(left)->HasStringValue()) || | 7814 ((left->IsConstant() && HConstant::cast(left)->IsString()) || |
| 7794 (right->IsConstant() && HConstant::cast(right)->HasStringValue()))) { | 7815 (right->IsConstant() && HConstant::cast(right)->IsString()))) { |
| 7795 return instr; | 7816 return instr; |
| 7796 } | 7817 } |
| 7797 Representation rep = ToRepresentation(info); | 7818 Representation rep = ToRepresentation(info); |
| 7798 // We only generate either int32 or generic tagged bitwise operations. | 7819 // We only generate either int32 or generic tagged bitwise operations. |
| 7799 if (instr->IsBitwiseBinaryOperation()) { | 7820 if (instr->IsBitwiseBinaryOperation()) { |
| 7800 HBitwiseBinaryOperation::cast(instr)-> | 7821 HBitwiseBinaryOperation::cast(instr)-> |
| 7801 InitializeObservedInputRepresentation(rep); | 7822 InitializeObservedInputRepresentation(rep); |
| 7802 if (rep.IsDouble()) rep = Representation::Integer32(); | 7823 if (rep.IsDouble()) rep = Representation::Integer32(); |
| 7803 } | 7824 } |
| 7804 TraceRepresentation(expr->op(), info, instr, rep); | 7825 TraceRepresentation(expr->op(), info, instr, rep); |
| (...skipping 177 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7982 HValue* value = typeof_expr->value(); | 8003 HValue* value = typeof_expr->value(); |
| 7983 HTypeofIsAndBranch* instr = new(zone()) HTypeofIsAndBranch(value, check); | 8004 HTypeofIsAndBranch* instr = new(zone()) HTypeofIsAndBranch(value, check); |
| 7984 instr->set_position(expr->position()); | 8005 instr->set_position(expr->position()); |
| 7985 return ast_context()->ReturnControl(instr, expr->id()); | 8006 return ast_context()->ReturnControl(instr, expr->id()); |
| 7986 } | 8007 } |
| 7987 | 8008 |
| 7988 | 8009 |
| 7989 static bool MatchLiteralCompareNil(HValue* left, | 8010 static bool MatchLiteralCompareNil(HValue* left, |
| 7990 Token::Value op, | 8011 Token::Value op, |
| 7991 HValue* right, | 8012 HValue* right, |
| 7992 Handle<Object> nil, | 8013 HConstant* nil, |
| 7993 HValue** expr) { | 8014 HValue** expr) { |
| 8015 ASSERT(nil->IsTagged()); |
| 7994 if (left->IsConstant() && | 8016 if (left->IsConstant() && |
| 7995 HConstant::cast(left)->handle().is_identical_to(nil) && | 8017 HConstant::cast(left)->IsTagged() && |
| 8018 HConstant::cast(left)->handle().is_identical_to(nil->handle()) && |
| 7996 Token::IsEqualityOp(op)) { | 8019 Token::IsEqualityOp(op)) { |
| 7997 *expr = right; | 8020 *expr = right; |
| 7998 return true; | 8021 return true; |
| 7999 } | 8022 } |
| 8000 return false; | 8023 return false; |
| 8001 } | 8024 } |
| 8002 | 8025 |
| 8003 | 8026 |
| 8004 static bool MatchLiteralCompareTypeof(HValue* left, | 8027 static bool MatchLiteralCompareTypeof(HValue* left, |
| 8005 Token::Value op, | 8028 Token::Value op, |
| 8006 HValue* right, | 8029 HValue* right, |
| 8007 HTypeof** typeof_expr, | 8030 HTypeof** typeof_expr, |
| 8008 Handle<String>* check) { | 8031 Handle<String>* check) { |
| 8009 if (left->IsTypeof() && | 8032 if (left->IsTypeof() && |
| 8010 Token::IsEqualityOp(op) && | 8033 Token::IsEqualityOp(op) && |
| 8011 right->IsConstant() && | 8034 right->IsConstant() && |
| 8012 HConstant::cast(right)->HasStringValue()) { | 8035 HConstant::cast(right)->IsString()) { |
| 8013 *typeof_expr = HTypeof::cast(left); | 8036 *typeof_expr = HTypeof::cast(left); |
| 8014 *check = Handle<String>::cast(HConstant::cast(right)->handle()); | 8037 *check = Handle<String>::cast(HConstant::cast(right)->handle()); |
| 8015 return true; | 8038 return true; |
| 8016 } | 8039 } |
| 8017 return false; | 8040 return false; |
| 8018 } | 8041 } |
| 8019 | 8042 |
| 8020 | 8043 |
| 8021 static bool IsLiteralCompareTypeof(HValue* left, | 8044 static bool IsLiteralCompareTypeof(HValue* left, |
| 8022 Token::Value op, | 8045 Token::Value op, |
| 8023 HValue* right, | 8046 HValue* right, |
| 8024 HTypeof** typeof_expr, | 8047 HTypeof** typeof_expr, |
| 8025 Handle<String>* check) { | 8048 Handle<String>* check) { |
| 8026 return MatchLiteralCompareTypeof(left, op, right, typeof_expr, check) || | 8049 return MatchLiteralCompareTypeof(left, op, right, typeof_expr, check) || |
| 8027 MatchLiteralCompareTypeof(right, op, left, typeof_expr, check); | 8050 MatchLiteralCompareTypeof(right, op, left, typeof_expr, check); |
| 8028 } | 8051 } |
| 8029 | 8052 |
| 8030 | 8053 |
| 8031 static bool IsLiteralCompareNil(HValue* left, | 8054 static bool IsLiteralCompareNil(HValue* left, |
| 8032 Token::Value op, | 8055 Token::Value op, |
| 8033 HValue* right, | 8056 HValue* right, |
| 8034 Handle<Object> nil, | 8057 HConstant* nil, |
| 8035 HValue** expr) { | 8058 HValue** expr) { |
| 8036 return MatchLiteralCompareNil(left, op, right, nil, expr) || | 8059 return MatchLiteralCompareNil(left, op, right, nil, expr) || |
| 8037 MatchLiteralCompareNil(right, op, left, nil, expr); | 8060 MatchLiteralCompareNil(right, op, left, nil, expr); |
| 8038 } | 8061 } |
| 8039 | 8062 |
| 8040 | 8063 |
| 8041 static bool IsLiteralCompareBool(HValue* left, | 8064 static bool IsLiteralCompareBool(HValue* left, |
| 8042 Token::Value op, | 8065 Token::Value op, |
| 8043 HValue* right) { | 8066 HValue* right) { |
| 8044 return op == Token::EQ_STRICT && | 8067 return op == Token::EQ_STRICT && |
| 8045 ((left->IsConstant() && HConstant::cast(left)->handle()->IsBoolean()) || | 8068 ((left->IsConstant() && |
| 8046 (right->IsConstant() && HConstant::cast(right)->handle()->IsBoolean())); | 8069 HConstant::cast(left)->IsBoolean()) || |
| 8070 (right->IsConstant() && |
| 8071 HConstant::cast(right)->IsBoolean())); |
| 8047 } | 8072 } |
| 8048 | 8073 |
| 8049 | 8074 |
| 8050 void HGraphBuilder::VisitCompareOperation(CompareOperation* expr) { | 8075 void HGraphBuilder::VisitCompareOperation(CompareOperation* expr) { |
| 8051 ASSERT(!HasStackOverflow()); | 8076 ASSERT(!HasStackOverflow()); |
| 8052 ASSERT(current_block() != NULL); | 8077 ASSERT(current_block() != NULL); |
| 8053 ASSERT(current_block()->HasPredecessor()); | 8078 ASSERT(current_block()->HasPredecessor()); |
| 8054 if (IsClassOfTest(expr)) { | 8079 if (IsClassOfTest(expr)) { |
| 8055 CallRuntime* call = expr->left()->AsCallRuntime(); | 8080 CallRuntime* call = expr->left()->AsCallRuntime(); |
| 8056 ASSERT(call->arguments()->length() == 1); | 8081 ASSERT(call->arguments()->length() == 1); |
| (...skipping 23 matching lines...) Expand all Loading... |
| 8080 HValue* right = Pop(); | 8105 HValue* right = Pop(); |
| 8081 HValue* left = Pop(); | 8106 HValue* left = Pop(); |
| 8082 Token::Value op = expr->op(); | 8107 Token::Value op = expr->op(); |
| 8083 | 8108 |
| 8084 HTypeof* typeof_expr = NULL; | 8109 HTypeof* typeof_expr = NULL; |
| 8085 Handle<String> check; | 8110 Handle<String> check; |
| 8086 if (IsLiteralCompareTypeof(left, op, right, &typeof_expr, &check)) { | 8111 if (IsLiteralCompareTypeof(left, op, right, &typeof_expr, &check)) { |
| 8087 return HandleLiteralCompareTypeof(expr, typeof_expr, check); | 8112 return HandleLiteralCompareTypeof(expr, typeof_expr, check); |
| 8088 } | 8113 } |
| 8089 HValue* sub_expr = NULL; | 8114 HValue* sub_expr = NULL; |
| 8090 Factory* f = graph()->isolate()->factory(); | 8115 if (IsLiteralCompareNil(left, op, right, constant_undefined_, &sub_expr)) { |
| 8091 if (IsLiteralCompareNil(left, op, right, f->undefined_value(), &sub_expr)) { | |
| 8092 return HandleLiteralCompareNil(expr, sub_expr, kUndefinedValue); | 8116 return HandleLiteralCompareNil(expr, sub_expr, kUndefinedValue); |
| 8093 } | 8117 } |
| 8094 if (IsLiteralCompareNil(left, op, right, f->null_value(), &sub_expr)) { | 8118 if (IsLiteralCompareNil(left, op, right, constant_null_, &sub_expr)) { |
| 8095 return HandleLiteralCompareNil(expr, sub_expr, kNullValue); | 8119 return HandleLiteralCompareNil(expr, sub_expr, kNullValue); |
| 8096 } | 8120 } |
| 8097 if (IsLiteralCompareBool(left, op, right)) { | 8121 if (IsLiteralCompareBool(left, op, right)) { |
| 8098 HCompareObjectEqAndBranch* result = | 8122 HCompareObjectEqAndBranch* result = |
| 8099 new(zone()) HCompareObjectEqAndBranch(left, right); | 8123 new(zone()) HCompareObjectEqAndBranch(left, right); |
| 8100 result->set_position(expr->position()); | 8124 result->set_position(expr->position()); |
| 8101 return ast_context()->ReturnControl(result, expr->id()); | 8125 return ast_context()->ReturnControl(result, expr->id()); |
| 8102 } | 8126 } |
| 8103 | 8127 |
| 8104 if (op == Token::INSTANCEOF) { | 8128 if (op == Token::INSTANCEOF) { |
| (...skipping 1332 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9437 } | 9461 } |
| 9438 } | 9462 } |
| 9439 | 9463 |
| 9440 #ifdef DEBUG | 9464 #ifdef DEBUG |
| 9441 if (graph_ != NULL) graph_->Verify(false); // No full verify. | 9465 if (graph_ != NULL) graph_->Verify(false); // No full verify. |
| 9442 if (allocator_ != NULL) allocator_->Verify(); | 9466 if (allocator_ != NULL) allocator_->Verify(); |
| 9443 #endif | 9467 #endif |
| 9444 } | 9468 } |
| 9445 | 9469 |
| 9446 } } // namespace v8::internal | 9470 } } // namespace v8::internal |
| OLD | NEW |