| 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 685 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|   696       zone_(info->zone()), |   696       zone_(info->zone()), | 
|   697       is_recursive_(false) { |   697       is_recursive_(false) { | 
|   698   start_environment_ = |   698   start_environment_ = | 
|   699       new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); |   699       new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); | 
|   700   start_environment_->set_ast_id(AstNode::kFunctionEntryId); |   700   start_environment_->set_ast_id(AstNode::kFunctionEntryId); | 
|   701   entry_block_ = CreateBasicBlock(); |   701   entry_block_ = CreateBasicBlock(); | 
|   702   entry_block_->SetInitialEnvironment(start_environment_); |   702   entry_block_->SetInitialEnvironment(start_environment_); | 
|   703 } |   703 } | 
|   704  |   704  | 
|   705  |   705  | 
|   706 Handle<Code> HGraph::Compile() { |  | 
|   707   int values = GetMaximumValueID(); |  | 
|   708   if (values > LUnallocated::kMaxVirtualRegisters) { |  | 
|   709     if (FLAG_trace_bailout) { |  | 
|   710       PrintF("Not enough virtual registers for (values).\n"); |  | 
|   711     } |  | 
|   712     return Handle<Code>::null(); |  | 
|   713   } |  | 
|   714   LAllocator allocator(values, this); |  | 
|   715   LChunkBuilder builder(info(), this, &allocator); |  | 
|   716   LChunk* chunk = builder.Build(); |  | 
|   717   if (chunk == NULL) return Handle<Code>::null(); |  | 
|   718  |  | 
|   719   if (!allocator.Allocate(chunk)) { |  | 
|   720     if (FLAG_trace_bailout) { |  | 
|   721       PrintF("Not enough virtual registers (regalloc).\n"); |  | 
|   722     } |  | 
|   723     return Handle<Code>::null(); |  | 
|   724   } |  | 
|   725  |  | 
|   726   MacroAssembler assembler(isolate(), NULL, 0); |  | 
|   727   LCodeGen generator(chunk, &assembler, info()); |  | 
|   728  |  | 
|   729   chunk->MarkEmptyBlocks(); |  | 
|   730  |  | 
|   731   if (generator.GenerateCode()) { |  | 
|   732     if (FLAG_trace_codegen) { |  | 
|   733       PrintF("Crankshaft Compiler - "); |  | 
|   734     } |  | 
|   735     CodeGenerator::MakeCodePrologue(info()); |  | 
|   736     Code::Flags flags = Code::ComputeFlags(Code::OPTIMIZED_FUNCTION); |  | 
|   737     Handle<Code> code = |  | 
|   738         CodeGenerator::MakeCodeEpilogue(&assembler, flags, info()); |  | 
|   739     generator.FinishCode(code); |  | 
|   740     CodeGenerator::PrintCode(code, info()); |  | 
|   741     return code; |  | 
|   742   } |  | 
|   743   return Handle<Code>::null(); |  | 
|   744 } |  | 
|   745  |  | 
|   746  |  | 
|   747 HBasicBlock* HGraph::CreateBasicBlock() { |   706 HBasicBlock* HGraph::CreateBasicBlock() { | 
|   748   HBasicBlock* result = new(zone()) HBasicBlock(this); |   707   HBasicBlock* result = new(zone()) HBasicBlock(this); | 
|   749   blocks_.Add(result, zone()); |   708   blocks_.Add(result, zone()); | 
|   750   return result; |   709   return result; | 
|   751 } |   710 } | 
|   752  |   711  | 
|   753  |   712  | 
|   754 void HGraph::Canonicalize() { |   713 void HGraph::Canonicalize() { | 
|   755   if (!FLAG_use_canonicalizing) return; |   714   if (!FLAG_use_canonicalizing) return; | 
|   756   HPhase phase("H_Canonicalize", this); |   715   HPhase phase("H_Canonicalize", this); | 
| (...skipping 2358 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  3115     VisitStatements(info()->function()->body()); |  3074     VisitStatements(info()->function()->body()); | 
|  3116     if (HasStackOverflow()) return NULL; |  3075     if (HasStackOverflow()) return NULL; | 
|  3117  |  3076  | 
|  3118     if (current_block() != NULL) { |  3077     if (current_block() != NULL) { | 
|  3119       HReturn* instr = new(zone()) HReturn(graph()->GetConstantUndefined()); |  3078       HReturn* instr = new(zone()) HReturn(graph()->GetConstantUndefined()); | 
|  3120       current_block()->FinishExit(instr); |  3079       current_block()->FinishExit(instr); | 
|  3121       set_current_block(NULL); |  3080       set_current_block(NULL); | 
|  3122     } |  3081     } | 
|  3123   } |  3082   } | 
|  3124  |  3083  | 
|  3125   graph()->OrderBlocks(); |  3084   return graph(); | 
|  3126   graph()->AssignDominators(); |  3085 } | 
 |  3086  | 
 |  3087 bool HGraph::Optimize(SmartArrayPointer<char>* bailout_reason) { | 
 |  3088   *bailout_reason = SmartArrayPointer<char>(); | 
 |  3089   OrderBlocks(); | 
 |  3090   AssignDominators(); | 
|  3127  |  3091  | 
|  3128 #ifdef DEBUG |  3092 #ifdef DEBUG | 
|  3129   // Do a full verify after building the graph and computing dominators. |  3093   // Do a full verify after building the graph and computing dominators. | 
|  3130   graph()->Verify(true); |  3094   Verify(true); | 
|  3131 #endif |  3095 #endif | 
|  3132  |  3096  | 
|  3133   graph()->PropagateDeoptimizingMark(); |  3097   PropagateDeoptimizingMark(); | 
|  3134   if (!graph()->CheckConstPhiUses()) { |  3098   if (!CheckConstPhiUses()) { | 
|  3135     Bailout("Unsupported phi use of const variable"); |  3099     *bailout_reason = SmartArrayPointer<char>(StrDup( | 
|  3136     return NULL; |  3100         "Unsupported phi use of const variable")); | 
 |  3101     return false; | 
|  3137   } |  3102   } | 
|  3138   graph()->EliminateRedundantPhis(); |  3103   EliminateRedundantPhis(); | 
|  3139   if (!graph()->CheckArgumentsPhiUses()) { |  3104   if (!CheckArgumentsPhiUses()) { | 
|  3140     Bailout("Unsupported phi use of arguments"); |  3105     *bailout_reason = SmartArrayPointer<char>(StrDup( | 
|  3141     return NULL; |  3106         "Unsupported phi use of arguments")); | 
 |  3107     return false; | 
|  3142   } |  3108   } | 
|  3143   if (FLAG_eliminate_dead_phis) graph()->EliminateUnreachablePhis(); |  3109   if (FLAG_eliminate_dead_phis) EliminateUnreachablePhis(); | 
|  3144   graph()->CollectPhis(); |  3110   CollectPhis(); | 
|  3145  |  3111  | 
|  3146   if (graph()->has_osr_loop_entry()) { |  3112   if (has_osr_loop_entry()) { | 
|  3147     const ZoneList<HPhi*>* phis = graph()->osr_loop_entry()->phis(); |  3113     const ZoneList<HPhi*>* phis = osr_loop_entry()->phis(); | 
|  3148     for (int j = 0; j < phis->length(); j++) { |  3114     for (int j = 0; j < phis->length(); j++) { | 
|  3149       HPhi* phi = phis->at(j); |  3115       HPhi* phi = phis->at(j); | 
|  3150       graph()->osr_values()->at(phi->merged_index())->set_incoming_value(phi); |  3116       osr_values()->at(phi->merged_index())->set_incoming_value(phi); | 
|  3151     } |  3117     } | 
|  3152   } |  3118   } | 
|  3153  |  3119  | 
|  3154   HInferRepresentation rep(graph()); |  3120   HInferRepresentation rep(this); | 
|  3155   rep.Analyze(); |  3121   rep.Analyze(); | 
|  3156  |  3122  | 
|  3157   graph()->MarkDeoptimizeOnUndefined(); |  3123   MarkDeoptimizeOnUndefined(); | 
|  3158   graph()->InsertRepresentationChanges(); |  3124   InsertRepresentationChanges(); | 
|  3159  |  3125  | 
|  3160   graph()->InitializeInferredTypes(); |  3126   InitializeInferredTypes(); | 
|  3161   graph()->Canonicalize(); |  3127   Canonicalize(); | 
|  3162  |  3128  | 
|  3163   // Perform common subexpression elimination and loop-invariant code motion. |  3129   // Perform common subexpression elimination and loop-invariant code motion. | 
|  3164   if (FLAG_use_gvn) { |  3130   if (FLAG_use_gvn) { | 
|  3165     HPhase phase("H_Global value numbering", graph()); |  3131     HPhase phase("H_Global value numbering", this); | 
|  3166     HGlobalValueNumberer gvn(graph(), info()); |  3132     HGlobalValueNumberer gvn(this, info()); | 
|  3167     bool removed_side_effects = gvn.Analyze(); |  3133     bool removed_side_effects = gvn.Analyze(); | 
|  3168     // Trigger a second analysis pass to further eliminate duplicate values that |  3134     // Trigger a second analysis pass to further eliminate duplicate values that | 
|  3169     // could only be discovered by removing side-effect-generating instructions |  3135     // could only be discovered by removing side-effect-generating instructions | 
|  3170     // during the first pass. |  3136     // during the first pass. | 
|  3171     if (FLAG_smi_only_arrays && removed_side_effects) { |  3137     if (FLAG_smi_only_arrays && removed_side_effects) { | 
|  3172       removed_side_effects = gvn.Analyze(); |  3138       removed_side_effects = gvn.Analyze(); | 
|  3173       ASSERT(!removed_side_effects); |  3139       ASSERT(!removed_side_effects); | 
|  3174     } |  3140     } | 
|  3175   } |  3141   } | 
|  3176  |  3142  | 
|  3177   if (FLAG_use_range) { |  3143   if (FLAG_use_range) { | 
|  3178     HRangeAnalysis rangeAnalysis(graph()); |  3144     HRangeAnalysis rangeAnalysis(this); | 
|  3179     rangeAnalysis.Analyze(); |  3145     rangeAnalysis.Analyze(); | 
|  3180   } |  3146   } | 
|  3181   graph()->ComputeMinusZeroChecks(); |  3147   ComputeMinusZeroChecks(); | 
|  3182  |  3148  | 
|  3183   // Eliminate redundant stack checks on backwards branches. |  3149   // Eliminate redundant stack checks on backwards branches. | 
|  3184   HStackCheckEliminator sce(graph()); |  3150   HStackCheckEliminator sce(this); | 
|  3185   sce.Process(); |  3151   sce.Process(); | 
|  3186  |  3152  | 
|  3187   graph()->EliminateRedundantBoundsChecks(); |  3153   EliminateRedundantBoundsChecks(); | 
|  3188   graph()->DehoistSimpleArrayIndexComputations(); |  3154   DehoistSimpleArrayIndexComputations(); | 
|  3189  |  3155  | 
|  3190   return graph(); |  3156   return true; | 
|  3191 } |  3157 } | 
|  3192  |  3158  | 
|  3193  |  3159  | 
|  3194 // We try to "factor up" HBoundsCheck instructions towards the root of the |  3160 // We try to "factor up" HBoundsCheck instructions towards the root of the | 
|  3195 // dominator tree. |  3161 // dominator tree. | 
|  3196 // For now we handle checks where the index is like "exp + int32value". |  3162 // For now we handle checks where the index is like "exp + int32value". | 
|  3197 // If in the dominator tree we check "exp + v1" and later (dominated) |  3163 // If in the dominator tree we check "exp + v1" and later (dominated) | 
|  3198 // "exp + v2", if v2 <= v1 we can safely remove the second check, and if |  3164 // "exp + v2", if v2 <= v1 we can safely remove the second check, and if | 
|  3199 // v2 > v1 we can use v2 in the 1st check and again remove the second. |  3165 // v2 > v1 we can use v2 in the 1st check and again remove the second. | 
|  3200 // To do so we keep a dictionary of all checks where the key if the pair |  3166 // To do so we keep a dictionary of all checks where the key if the pair | 
| (...skipping 6365 matching lines...) Expand 10 before | Expand all | Expand 10 after  Loading... | 
|  9566     } |  9532     } | 
|  9567   } |  9533   } | 
|  9568  |  9534  | 
|  9569 #ifdef DEBUG |  9535 #ifdef DEBUG | 
|  9570   if (graph_ != NULL) graph_->Verify(false);  // No full verify. |  9536   if (graph_ != NULL) graph_->Verify(false);  // No full verify. | 
|  9571   if (allocator_ != NULL) allocator_->Verify(); |  9537   if (allocator_ != NULL) allocator_->Verify(); | 
|  9572 #endif |  9538 #endif | 
|  9573 } |  9539 } | 
|  9574  |  9540  | 
|  9575 } }  // namespace v8::internal |  9541 } }  // namespace v8::internal | 
| OLD | NEW |