| 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 125 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 136 | 136 |
| 137 void HBasicBlock::RemovePhi(HPhi* phi) { | 137 void HBasicBlock::RemovePhi(HPhi* phi) { |
| 138 ASSERT(phi->block() == this); | 138 ASSERT(phi->block() == this); |
| 139 ASSERT(phis_.Contains(phi)); | 139 ASSERT(phis_.Contains(phi)); |
| 140 phi->Kill(); | 140 phi->Kill(); |
| 141 phis_.RemoveElement(phi); | 141 phis_.RemoveElement(phi); |
| 142 phi->SetBlock(NULL); | 142 phi->SetBlock(NULL); |
| 143 } | 143 } |
| 144 | 144 |
| 145 | 145 |
| 146 void HBasicBlock::AddInstruction(HInstruction* instr, int position) { | 146 void HBasicBlock::AddInstruction(HInstruction* instr, |
| 147 HSourcePosition position) { |
| 147 ASSERT(!IsStartBlock() || !IsFinished()); | 148 ASSERT(!IsStartBlock() || !IsFinished()); |
| 148 ASSERT(!instr->IsLinked()); | 149 ASSERT(!instr->IsLinked()); |
| 149 ASSERT(!IsFinished()); | 150 ASSERT(!IsFinished()); |
| 150 | 151 |
| 151 if (position != RelocInfo::kNoPosition) { | 152 if (!position.IsUnknown()) { |
| 152 instr->set_position(position); | 153 instr->set_position(position); |
| 153 } | 154 } |
| 154 if (first_ == NULL) { | 155 if (first_ == NULL) { |
| 155 ASSERT(last_environment() != NULL); | 156 ASSERT(last_environment() != NULL); |
| 156 ASSERT(!last_environment()->ast_id().IsNone()); | 157 ASSERT(!last_environment()->ast_id().IsNone()); |
| 157 HBlockEntry* entry = new(zone()) HBlockEntry(); | 158 HBlockEntry* entry = new(zone()) HBlockEntry(); |
| 158 entry->InitializeAsFirst(this); | 159 entry->InitializeAsFirst(this); |
| 159 if (position != RelocInfo::kNoPosition) { | 160 if (!position.IsUnknown()) { |
| 160 entry->set_position(position); | 161 entry->set_position(position); |
| 161 } else { | 162 } else { |
| 162 ASSERT(!FLAG_emit_opt_code_positions || | 163 ASSERT(!FLAG_hydrogen_track_positions || |
| 163 !graph()->info()->IsOptimizing()); | 164 !graph()->info()->IsOptimizing()); |
| 164 } | 165 } |
| 165 first_ = last_ = entry; | 166 first_ = last_ = entry; |
| 166 } | 167 } |
| 167 instr->InsertAfter(last_); | 168 instr->InsertAfter(last_); |
| 168 } | 169 } |
| 169 | 170 |
| 170 | 171 |
| 171 HPhi* HBasicBlock::AddNewPhi(int merged_index) { | 172 HPhi* HBasicBlock::AddNewPhi(int merged_index) { |
| 172 if (graph()->IsInsideNoSideEffectsScope()) { | 173 if (graph()->IsInsideNoSideEffectsScope()) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 205 !it.Done(); | 206 !it.Done(); |
| 206 it.Advance()) { | 207 it.Advance()) { |
| 207 int index = it.Current(); | 208 int index = it.Current(); |
| 208 instr->AddAssignedValue(index, environment->Lookup(index)); | 209 instr->AddAssignedValue(index, environment->Lookup(index)); |
| 209 } | 210 } |
| 210 environment->ClearHistory(); | 211 environment->ClearHistory(); |
| 211 return instr; | 212 return instr; |
| 212 } | 213 } |
| 213 | 214 |
| 214 | 215 |
| 215 void HBasicBlock::Finish(HControlInstruction* end, int position) { | 216 void HBasicBlock::Finish(HControlInstruction* end, HSourcePosition position) { |
| 216 ASSERT(!IsFinished()); | 217 ASSERT(!IsFinished()); |
| 217 AddInstruction(end, position); | 218 AddInstruction(end, position); |
| 218 end_ = end; | 219 end_ = end; |
| 219 for (HSuccessorIterator it(end); !it.Done(); it.Advance()) { | 220 for (HSuccessorIterator it(end); !it.Done(); it.Advance()) { |
| 220 it.Current()->RegisterPredecessor(this); | 221 it.Current()->RegisterPredecessor(this); |
| 221 } | 222 } |
| 222 } | 223 } |
| 223 | 224 |
| 224 | 225 |
| 225 void HBasicBlock::Goto(HBasicBlock* block, | 226 void HBasicBlock::Goto(HBasicBlock* block, |
| 226 int position, | 227 HSourcePosition position, |
| 227 FunctionState* state, | 228 FunctionState* state, |
| 228 bool add_simulate) { | 229 bool add_simulate) { |
| 229 bool drop_extra = state != NULL && | 230 bool drop_extra = state != NULL && |
| 230 state->inlining_kind() == NORMAL_RETURN; | 231 state->inlining_kind() == NORMAL_RETURN; |
| 231 | 232 |
| 232 if (block->IsInlineReturnTarget()) { | 233 if (block->IsInlineReturnTarget()) { |
| 233 HEnvironment* env = last_environment(); | 234 HEnvironment* env = last_environment(); |
| 234 int argument_count = env->arguments_environment()->parameter_count(); | 235 int argument_count = env->arguments_environment()->parameter_count(); |
| 235 AddInstruction(new(zone()) | 236 AddInstruction(new(zone()) |
| 236 HLeaveInlined(state->entry(), argument_count), | 237 HLeaveInlined(state->entry(), argument_count), |
| 237 position); | 238 position); |
| 238 UpdateEnvironment(last_environment()->DiscardInlined(drop_extra)); | 239 UpdateEnvironment(last_environment()->DiscardInlined(drop_extra)); |
| 239 } | 240 } |
| 240 | 241 |
| 241 if (add_simulate) AddNewSimulate(BailoutId::None(), position); | 242 if (add_simulate) AddNewSimulate(BailoutId::None(), position); |
| 242 HGoto* instr = new(zone()) HGoto(block); | 243 HGoto* instr = new(zone()) HGoto(block); |
| 243 Finish(instr, position); | 244 Finish(instr, position); |
| 244 } | 245 } |
| 245 | 246 |
| 246 | 247 |
| 247 void HBasicBlock::AddLeaveInlined(HValue* return_value, | 248 void HBasicBlock::AddLeaveInlined(HValue* return_value, |
| 248 FunctionState* state, | 249 FunctionState* state, |
| 249 int position) { | 250 HSourcePosition position) { |
| 250 HBasicBlock* target = state->function_return(); | 251 HBasicBlock* target = state->function_return(); |
| 251 bool drop_extra = state->inlining_kind() == NORMAL_RETURN; | 252 bool drop_extra = state->inlining_kind() == NORMAL_RETURN; |
| 252 | 253 |
| 253 ASSERT(target->IsInlineReturnTarget()); | 254 ASSERT(target->IsInlineReturnTarget()); |
| 254 ASSERT(return_value != NULL); | 255 ASSERT(return_value != NULL); |
| 255 HEnvironment* env = last_environment(); | 256 HEnvironment* env = last_environment(); |
| 256 int argument_count = env->arguments_environment()->parameter_count(); | 257 int argument_count = env->arguments_environment()->parameter_count(); |
| 257 AddInstruction(new(zone()) HLeaveInlined(state->entry(), argument_count), | 258 AddInstruction(new(zone()) HLeaveInlined(state->entry(), argument_count), |
| 258 position); | 259 position); |
| 259 UpdateEnvironment(last_environment()->DiscardInlined(drop_extra)); | 260 UpdateEnvironment(last_environment()->DiscardInlined(drop_extra)); |
| (...skipping 911 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1171 CompilationPhase phase("H_Block building", info_); | 1172 CompilationPhase phase("H_Block building", info_); |
| 1172 set_current_block(graph()->entry_block()); | 1173 set_current_block(graph()->entry_block()); |
| 1173 if (!BuildGraph()) return NULL; | 1174 if (!BuildGraph()) return NULL; |
| 1174 graph()->FinalizeUniqueness(); | 1175 graph()->FinalizeUniqueness(); |
| 1175 return graph_; | 1176 return graph_; |
| 1176 } | 1177 } |
| 1177 | 1178 |
| 1178 | 1179 |
| 1179 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { | 1180 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { |
| 1180 ASSERT(current_block() != NULL); | 1181 ASSERT(current_block() != NULL); |
| 1181 ASSERT(!FLAG_emit_opt_code_positions || | 1182 ASSERT(!FLAG_hydrogen_track_positions || |
| 1182 position_ != RelocInfo::kNoPosition || !info_->IsOptimizing()); | 1183 !position_.IsUnknown() || |
| 1183 current_block()->AddInstruction(instr, position_); | 1184 !info_->IsOptimizing()); |
| 1185 current_block()->AddInstruction(instr, source_position()); |
| 1184 if (graph()->IsInsideNoSideEffectsScope()) { | 1186 if (graph()->IsInsideNoSideEffectsScope()) { |
| 1185 instr->SetFlag(HValue::kHasNoObservableSideEffects); | 1187 instr->SetFlag(HValue::kHasNoObservableSideEffects); |
| 1186 } | 1188 } |
| 1187 return instr; | 1189 return instr; |
| 1188 } | 1190 } |
| 1189 | 1191 |
| 1190 | 1192 |
| 1191 void HGraphBuilder::FinishCurrentBlock(HControlInstruction* last) { | 1193 void HGraphBuilder::FinishCurrentBlock(HControlInstruction* last) { |
| 1192 ASSERT(!FLAG_emit_opt_code_positions || !info_->IsOptimizing() || | 1194 ASSERT(!FLAG_hydrogen_track_positions || |
| 1193 position_ != RelocInfo::kNoPosition); | 1195 !info_->IsOptimizing() || |
| 1194 current_block()->Finish(last, position_); | 1196 !position_.IsUnknown()); |
| 1197 current_block()->Finish(last, source_position()); |
| 1195 if (last->IsReturn() || last->IsAbnormalExit()) { | 1198 if (last->IsReturn() || last->IsAbnormalExit()) { |
| 1196 set_current_block(NULL); | 1199 set_current_block(NULL); |
| 1197 } | 1200 } |
| 1198 } | 1201 } |
| 1199 | 1202 |
| 1200 | 1203 |
| 1201 void HGraphBuilder::FinishExitCurrentBlock(HControlInstruction* instruction) { | 1204 void HGraphBuilder::FinishExitCurrentBlock(HControlInstruction* instruction) { |
| 1202 ASSERT(!FLAG_emit_opt_code_positions || !info_->IsOptimizing() || | 1205 ASSERT(!FLAG_hydrogen_track_positions || !info_->IsOptimizing() || |
| 1203 position_ != RelocInfo::kNoPosition); | 1206 !position_.IsUnknown()); |
| 1204 current_block()->FinishExit(instruction, position_); | 1207 current_block()->FinishExit(instruction, source_position()); |
| 1205 if (instruction->IsReturn() || instruction->IsAbnormalExit()) { | 1208 if (instruction->IsReturn() || instruction->IsAbnormalExit()) { |
| 1206 set_current_block(NULL); | 1209 set_current_block(NULL); |
| 1207 } | 1210 } |
| 1208 } | 1211 } |
| 1209 | 1212 |
| 1210 | 1213 |
| 1211 void HGraphBuilder::AddIncrementCounter(StatsCounter* counter) { | 1214 void HGraphBuilder::AddIncrementCounter(StatsCounter* counter) { |
| 1212 if (FLAG_native_code_counters && counter->Enabled()) { | 1215 if (FLAG_native_code_counters && counter->Enabled()) { |
| 1213 HValue* reference = Add<HConstant>(ExternalReference(counter)); | 1216 HValue* reference = Add<HConstant>(ExternalReference(counter)); |
| 1214 HValue* old_value = Add<HLoadNamedField>( | 1217 HValue* old_value = Add<HLoadNamedField>( |
| 1215 reference, static_cast<HValue*>(NULL), HObjectAccess::ForCounter()); | 1218 reference, static_cast<HValue*>(NULL), HObjectAccess::ForCounter()); |
| 1216 HValue* new_value = AddUncasted<HAdd>(old_value, graph()->GetConstant1()); | 1219 HValue* new_value = AddUncasted<HAdd>(old_value, graph()->GetConstant1()); |
| 1217 new_value->ClearFlag(HValue::kCanOverflow); // Ignore counter overflow | 1220 new_value->ClearFlag(HValue::kCanOverflow); // Ignore counter overflow |
| 1218 Add<HStoreNamedField>(reference, HObjectAccess::ForCounter(), | 1221 Add<HStoreNamedField>(reference, HObjectAccess::ForCounter(), |
| 1219 new_value, STORE_TO_INITIALIZED_ENTRY); | 1222 new_value, STORE_TO_INITIALIZED_ENTRY); |
| 1220 } | 1223 } |
| 1221 } | 1224 } |
| 1222 | 1225 |
| 1223 | 1226 |
| 1224 void HGraphBuilder::AddSimulate(BailoutId id, | 1227 void HGraphBuilder::AddSimulate(BailoutId id, |
| 1225 RemovableSimulate removable) { | 1228 RemovableSimulate removable) { |
| 1226 ASSERT(current_block() != NULL); | 1229 ASSERT(current_block() != NULL); |
| 1227 ASSERT(!graph()->IsInsideNoSideEffectsScope()); | 1230 ASSERT(!graph()->IsInsideNoSideEffectsScope()); |
| 1228 current_block()->AddNewSimulate(id, position_, removable); | 1231 current_block()->AddNewSimulate(id, source_position(), removable); |
| 1229 } | 1232 } |
| 1230 | 1233 |
| 1231 | 1234 |
| 1232 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { | 1235 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { |
| 1233 HBasicBlock* b = graph()->CreateBasicBlock(); | 1236 HBasicBlock* b = graph()->CreateBasicBlock(); |
| 1234 b->SetInitialEnvironment(env); | 1237 b->SetInitialEnvironment(env); |
| 1235 return b; | 1238 return b; |
| 1236 } | 1239 } |
| 1237 | 1240 |
| 1238 | 1241 |
| (...skipping 1760 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2999 HObjectAccess function_access = HObjectAccess::ForObservableJSObjectOffset( | 3002 HObjectAccess function_access = HObjectAccess::ForObservableJSObjectOffset( |
| 3000 JSBuiltinsObject::OffsetOfFunctionWithId(builtin)); | 3003 JSBuiltinsObject::OffsetOfFunctionWithId(builtin)); |
| 3001 return Add<HLoadNamedField>( | 3004 return Add<HLoadNamedField>( |
| 3002 builtins, static_cast<HValue*>(NULL), function_access); | 3005 builtins, static_cast<HValue*>(NULL), function_access); |
| 3003 } | 3006 } |
| 3004 | 3007 |
| 3005 | 3008 |
| 3006 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info) | 3009 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info) |
| 3007 : HGraphBuilder(info), | 3010 : HGraphBuilder(info), |
| 3008 function_state_(NULL), | 3011 function_state_(NULL), |
| 3009 initial_function_state_(this, info, NORMAL_RETURN), | 3012 initial_function_state_(this, info, NORMAL_RETURN, 0), |
| 3010 ast_context_(NULL), | 3013 ast_context_(NULL), |
| 3011 break_scope_(NULL), | 3014 break_scope_(NULL), |
| 3012 inlined_count_(0), | 3015 inlined_count_(0), |
| 3013 globals_(10, info->zone()), | 3016 globals_(10, info->zone()), |
| 3014 inline_bailout_(false), | 3017 inline_bailout_(false), |
| 3015 osr_(new(info->zone()) HOsrBuilder(this)) { | 3018 osr_(new(info->zone()) HOsrBuilder(this)) { |
| 3016 // This is not initialized in the initializer list because the | 3019 // This is not initialized in the initializer list because the |
| 3017 // constructor for the initial state relies on function_state_ == NULL | 3020 // constructor for the initial state relies on function_state_ == NULL |
| 3018 // to know it's the initial state. | 3021 // to know it's the initial state. |
| 3019 function_state_= &initial_function_state_; | 3022 function_state_= &initial_function_state_; |
| 3020 InitializeAstVisitor(info->zone()); | 3023 InitializeAstVisitor(info->zone()); |
| 3021 if (FLAG_emit_opt_code_positions) { | 3024 if (FLAG_hydrogen_track_positions) { |
| 3022 SetSourcePosition(info->shared_info()->start_position()); | 3025 SetSourcePosition(info->shared_info()->start_position()); |
| 3023 } | 3026 } |
| 3024 } | 3027 } |
| 3025 | 3028 |
| 3026 | 3029 |
| 3027 HBasicBlock* HOptimizedGraphBuilder::CreateJoin(HBasicBlock* first, | 3030 HBasicBlock* HOptimizedGraphBuilder::CreateJoin(HBasicBlock* first, |
| 3028 HBasicBlock* second, | 3031 HBasicBlock* second, |
| 3029 BailoutId join_id) { | 3032 BailoutId join_id) { |
| 3030 if (first == NULL) { | 3033 if (first == NULL) { |
| 3031 return second; | 3034 return second; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3080 | 3083 |
| 3081 HBasicBlock* HOptimizedGraphBuilder::BuildLoopEntry( | 3084 HBasicBlock* HOptimizedGraphBuilder::BuildLoopEntry( |
| 3082 IterationStatement* statement) { | 3085 IterationStatement* statement) { |
| 3083 HBasicBlock* loop_entry = osr()->HasOsrEntryAt(statement) | 3086 HBasicBlock* loop_entry = osr()->HasOsrEntryAt(statement) |
| 3084 ? osr()->BuildOsrLoopEntry(statement) | 3087 ? osr()->BuildOsrLoopEntry(statement) |
| 3085 : BuildLoopEntry(); | 3088 : BuildLoopEntry(); |
| 3086 return loop_entry; | 3089 return loop_entry; |
| 3087 } | 3090 } |
| 3088 | 3091 |
| 3089 | 3092 |
| 3090 void HBasicBlock::FinishExit(HControlInstruction* instruction, int position) { | 3093 void HBasicBlock::FinishExit(HControlInstruction* instruction, |
| 3094 HSourcePosition position) { |
| 3091 Finish(instruction, position); | 3095 Finish(instruction, position); |
| 3092 ClearEnvironment(); | 3096 ClearEnvironment(); |
| 3093 } | 3097 } |
| 3094 | 3098 |
| 3095 | 3099 |
| 3096 HGraph::HGraph(CompilationInfo* info) | 3100 HGraph::HGraph(CompilationInfo* info) |
| 3097 : isolate_(info->isolate()), | 3101 : isolate_(info->isolate()), |
| 3098 next_block_id_(0), | 3102 next_block_id_(0), |
| 3099 entry_block_(NULL), | 3103 entry_block_(NULL), |
| 3100 blocks_(8, info->zone()), | 3104 blocks_(8, info->zone()), |
| 3101 values_(16, info->zone()), | 3105 values_(16, info->zone()), |
| 3102 phi_list_(NULL), | 3106 phi_list_(NULL), |
| 3103 uint32_instructions_(NULL), | 3107 uint32_instructions_(NULL), |
| 3104 osr_(NULL), | 3108 osr_(NULL), |
| 3105 info_(info), | 3109 info_(info), |
| 3106 zone_(info->zone()), | 3110 zone_(info->zone()), |
| 3107 is_recursive_(false), | 3111 is_recursive_(false), |
| 3108 use_optimistic_licm_(false), | 3112 use_optimistic_licm_(false), |
| 3109 depends_on_empty_array_proto_elements_(false), | 3113 depends_on_empty_array_proto_elements_(false), |
| 3110 type_change_checksum_(0), | 3114 type_change_checksum_(0), |
| 3111 maximum_environment_size_(0), | 3115 maximum_environment_size_(0), |
| 3112 no_side_effects_scope_count_(0), | 3116 no_side_effects_scope_count_(0), |
| 3113 disallow_adding_new_values_(false) { | 3117 disallow_adding_new_values_(false), |
| 3118 next_inline_id_(0), |
| 3119 inlined_functions_(5, info->zone()) { |
| 3114 if (info->IsStub()) { | 3120 if (info->IsStub()) { |
| 3115 HydrogenCodeStub* stub = info->code_stub(); | 3121 HydrogenCodeStub* stub = info->code_stub(); |
| 3116 CodeStubInterfaceDescriptor* descriptor = | 3122 CodeStubInterfaceDescriptor* descriptor = |
| 3117 stub->GetInterfaceDescriptor(isolate_); | 3123 stub->GetInterfaceDescriptor(isolate_); |
| 3118 start_environment_ = | 3124 start_environment_ = |
| 3119 new(zone_) HEnvironment(zone_, descriptor->environment_length()); | 3125 new(zone_) HEnvironment(zone_, descriptor->environment_length()); |
| 3120 } else { | 3126 } else { |
| 3127 TraceInlinedFunction(info->shared_info(), HSourcePosition::Unknown()); |
| 3121 start_environment_ = | 3128 start_environment_ = |
| 3122 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); | 3129 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); |
| 3123 } | 3130 } |
| 3124 start_environment_->set_ast_id(BailoutId::FunctionEntry()); | 3131 start_environment_->set_ast_id(BailoutId::FunctionEntry()); |
| 3125 entry_block_ = CreateBasicBlock(); | 3132 entry_block_ = CreateBasicBlock(); |
| 3126 entry_block_->SetInitialEnvironment(start_environment_); | 3133 entry_block_->SetInitialEnvironment(start_environment_); |
| 3127 } | 3134 } |
| 3128 | 3135 |
| 3129 | 3136 |
| 3130 HBasicBlock* HGraph::CreateBasicBlock() { | 3137 HBasicBlock* HGraph::CreateBasicBlock() { |
| 3131 HBasicBlock* result = new(zone()) HBasicBlock(this); | 3138 HBasicBlock* result = new(zone()) HBasicBlock(this); |
| 3132 blocks_.Add(result, zone()); | 3139 blocks_.Add(result, zone()); |
| 3133 return result; | 3140 return result; |
| 3134 } | 3141 } |
| 3135 | 3142 |
| 3136 | 3143 |
| 3137 void HGraph::FinalizeUniqueness() { | 3144 void HGraph::FinalizeUniqueness() { |
| 3138 DisallowHeapAllocation no_gc; | 3145 DisallowHeapAllocation no_gc; |
| 3139 ASSERT(!OptimizingCompilerThread::IsOptimizerThread(isolate())); | 3146 ASSERT(!OptimizingCompilerThread::IsOptimizerThread(isolate())); |
| 3140 for (int i = 0; i < blocks()->length(); ++i) { | 3147 for (int i = 0; i < blocks()->length(); ++i) { |
| 3141 for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) { | 3148 for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) { |
| 3142 it.Current()->FinalizeUniqueness(); | 3149 it.Current()->FinalizeUniqueness(); |
| 3143 } | 3150 } |
| 3144 } | 3151 } |
| 3145 } | 3152 } |
| 3146 | 3153 |
| 3147 | 3154 |
| 3155 int HGraph::TraceInlinedFunction( |
| 3156 Handle<SharedFunctionInfo> shared, |
| 3157 HSourcePosition position) { |
| 3158 if (!FLAG_hydrogen_track_positions) { |
| 3159 return 0; |
| 3160 } |
| 3161 |
| 3162 int id = 0; |
| 3163 for (; id < inlined_functions_.length(); id++) { |
| 3164 if (inlined_functions_[id].shared().is_identical_to(shared)) { |
| 3165 break; |
| 3166 } |
| 3167 } |
| 3168 |
| 3169 if (id == inlined_functions_.length()) { |
| 3170 inlined_functions_.Add(InlinedFunctionInfo(shared), zone()); |
| 3171 |
| 3172 if (!shared->script()->IsUndefined()) { |
| 3173 Handle<Script> script(Script::cast(shared->script())); |
| 3174 if (!script->source()->IsUndefined()) { |
| 3175 CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer()); |
| 3176 PrintF(tracing_scope.file(), |
| 3177 "--- FUNCTION SOURCE (%s) id{%d,%d} ---\n", |
| 3178 shared->DebugName()->ToCString().get(), |
| 3179 info()->optimization_id(), |
| 3180 id); |
| 3181 |
| 3182 { |
| 3183 ConsStringIteratorOp op; |
| 3184 StringCharacterStream stream(String::cast(script->source()), |
| 3185 &op, |
| 3186 shared->start_position()); |
| 3187 // fun->end_position() points to the last character in the stream. We |
| 3188 // need to compensate by adding one to calculate the length. |
| 3189 int source_len = |
| 3190 shared->end_position() - shared->start_position() + 1; |
| 3191 for (int i = 0; i < source_len; i++) { |
| 3192 if (stream.HasMore()) { |
| 3193 PrintF(tracing_scope.file(), "%c", stream.GetNext()); |
| 3194 } |
| 3195 } |
| 3196 } |
| 3197 |
| 3198 PrintF(tracing_scope.file(), "\n--- END ---\n"); |
| 3199 } |
| 3200 } |
| 3201 } |
| 3202 |
| 3203 int inline_id = next_inline_id_++; |
| 3204 |
| 3205 if (inline_id != 0) { |
| 3206 CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer()); |
| 3207 PrintF(tracing_scope.file(), "INLINE (%s) id{%d,%d} AS %d AT ", |
| 3208 shared->DebugName()->ToCString().get(), |
| 3209 info()->optimization_id(), |
| 3210 id, |
| 3211 inline_id); |
| 3212 position.PrintTo(tracing_scope.file()); |
| 3213 PrintF(tracing_scope.file(), "\n"); |
| 3214 } |
| 3215 |
| 3216 return inline_id; |
| 3217 } |
| 3218 |
| 3219 |
| 3220 int HGraph::SourcePositionToScriptPosition(HSourcePosition pos) { |
| 3221 if (!FLAG_hydrogen_track_positions || pos.IsUnknown()) { |
| 3222 return pos.raw(); |
| 3223 } |
| 3224 |
| 3225 return inlined_functions_[pos.inlining_id()].start_position() + |
| 3226 pos.position(); |
| 3227 } |
| 3228 |
| 3229 |
| 3148 // Block ordering was implemented with two mutually recursive methods, | 3230 // Block ordering was implemented with two mutually recursive methods, |
| 3149 // HGraph::Postorder and HGraph::PostorderLoopBlocks. | 3231 // HGraph::Postorder and HGraph::PostorderLoopBlocks. |
| 3150 // The recursion could lead to stack overflow so the algorithm has been | 3232 // The recursion could lead to stack overflow so the algorithm has been |
| 3151 // implemented iteratively. | 3233 // implemented iteratively. |
| 3152 // At a high level the algorithm looks like this: | 3234 // At a high level the algorithm looks like this: |
| 3153 // | 3235 // |
| 3154 // Postorder(block, loop_header) : { | 3236 // Postorder(block, loop_header) : { |
| 3155 // if (block has already been visited or is of another loop) return; | 3237 // if (block has already been visited or is of another loop) return; |
| 3156 // mark block as visited; | 3238 // mark block as visited; |
| 3157 // if (block is a loop header) { | 3239 // if (block is a loop header) { |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3516 phi_list_->Add(phi, zone()); | 3598 phi_list_->Add(phi, zone()); |
| 3517 } | 3599 } |
| 3518 } | 3600 } |
| 3519 } | 3601 } |
| 3520 | 3602 |
| 3521 | 3603 |
| 3522 // Implementation of utility class to encapsulate the translation state for | 3604 // Implementation of utility class to encapsulate the translation state for |
| 3523 // a (possibly inlined) function. | 3605 // a (possibly inlined) function. |
| 3524 FunctionState::FunctionState(HOptimizedGraphBuilder* owner, | 3606 FunctionState::FunctionState(HOptimizedGraphBuilder* owner, |
| 3525 CompilationInfo* info, | 3607 CompilationInfo* info, |
| 3526 InliningKind inlining_kind) | 3608 InliningKind inlining_kind, |
| 3609 int inlining_id) |
| 3527 : owner_(owner), | 3610 : owner_(owner), |
| 3528 compilation_info_(info), | 3611 compilation_info_(info), |
| 3529 call_context_(NULL), | 3612 call_context_(NULL), |
| 3530 inlining_kind_(inlining_kind), | 3613 inlining_kind_(inlining_kind), |
| 3531 function_return_(NULL), | 3614 function_return_(NULL), |
| 3532 test_context_(NULL), | 3615 test_context_(NULL), |
| 3533 entry_(NULL), | 3616 entry_(NULL), |
| 3534 arguments_object_(NULL), | 3617 arguments_object_(NULL), |
| 3535 arguments_elements_(NULL), | 3618 arguments_elements_(NULL), |
| 3619 inlining_id_(inlining_id), |
| 3620 outer_source_position_(HSourcePosition::Unknown()), |
| 3536 outer_(owner->function_state()) { | 3621 outer_(owner->function_state()) { |
| 3537 if (outer_ != NULL) { | 3622 if (outer_ != NULL) { |
| 3538 // State for an inline function. | 3623 // State for an inline function. |
| 3539 if (owner->ast_context()->IsTest()) { | 3624 if (owner->ast_context()->IsTest()) { |
| 3540 HBasicBlock* if_true = owner->graph()->CreateBasicBlock(); | 3625 HBasicBlock* if_true = owner->graph()->CreateBasicBlock(); |
| 3541 HBasicBlock* if_false = owner->graph()->CreateBasicBlock(); | 3626 HBasicBlock* if_false = owner->graph()->CreateBasicBlock(); |
| 3542 if_true->MarkAsInlineReturnTarget(owner->current_block()); | 3627 if_true->MarkAsInlineReturnTarget(owner->current_block()); |
| 3543 if_false->MarkAsInlineReturnTarget(owner->current_block()); | 3628 if_false->MarkAsInlineReturnTarget(owner->current_block()); |
| 3544 TestContext* outer_test_context = TestContext::cast(owner->ast_context()); | 3629 TestContext* outer_test_context = TestContext::cast(owner->ast_context()); |
| 3545 Expression* cond = outer_test_context->condition(); | 3630 Expression* cond = outer_test_context->condition(); |
| 3546 // The AstContext constructor pushed on the context stack. This newed | 3631 // The AstContext constructor pushed on the context stack. This newed |
| 3547 // instance is the reason that AstContext can't be BASE_EMBEDDED. | 3632 // instance is the reason that AstContext can't be BASE_EMBEDDED. |
| 3548 test_context_ = new TestContext(owner, cond, if_true, if_false); | 3633 test_context_ = new TestContext(owner, cond, if_true, if_false); |
| 3549 } else { | 3634 } else { |
| 3550 function_return_ = owner->graph()->CreateBasicBlock(); | 3635 function_return_ = owner->graph()->CreateBasicBlock(); |
| 3551 function_return()->MarkAsInlineReturnTarget(owner->current_block()); | 3636 function_return()->MarkAsInlineReturnTarget(owner->current_block()); |
| 3552 } | 3637 } |
| 3553 // Set this after possibly allocating a new TestContext above. | 3638 // Set this after possibly allocating a new TestContext above. |
| 3554 call_context_ = owner->ast_context(); | 3639 call_context_ = owner->ast_context(); |
| 3555 } | 3640 } |
| 3556 | 3641 |
| 3557 // Push on the state stack. | 3642 // Push on the state stack. |
| 3558 owner->set_function_state(this); | 3643 owner->set_function_state(this); |
| 3644 |
| 3645 if (FLAG_hydrogen_track_positions) { |
| 3646 outer_source_position_ = owner->source_position(); |
| 3647 owner->EnterInlinedSource( |
| 3648 info->shared_info()->start_position(), |
| 3649 inlining_id); |
| 3650 owner->SetSourcePosition(info->shared_info()->start_position()); |
| 3651 } |
| 3559 } | 3652 } |
| 3560 | 3653 |
| 3561 | 3654 |
| 3562 FunctionState::~FunctionState() { | 3655 FunctionState::~FunctionState() { |
| 3563 delete test_context_; | 3656 delete test_context_; |
| 3564 owner_->set_function_state(outer_); | 3657 owner_->set_function_state(outer_); |
| 3658 |
| 3659 if (FLAG_hydrogen_track_positions) { |
| 3660 owner_->set_source_position(outer_source_position_); |
| 3661 owner_->EnterInlinedSource( |
| 3662 outer_->compilation_info()->shared_info()->start_position(), |
| 3663 outer_->inlining_id()); |
| 3664 } |
| 3565 } | 3665 } |
| 3566 | 3666 |
| 3567 | 3667 |
| 3568 // Implementation of utility classes to represent an expression's context in | 3668 // Implementation of utility classes to represent an expression's context in |
| 3569 // the AST. | 3669 // the AST. |
| 3570 AstContext::AstContext(HOptimizedGraphBuilder* owner, Expression::Context kind) | 3670 AstContext::AstContext(HOptimizedGraphBuilder* owner, Expression::Context kind) |
| 3571 : owner_(owner), | 3671 : owner_(owner), |
| 3572 kind_(kind), | 3672 kind_(kind), |
| 3573 outer_(owner->ast_context()), | 3673 outer_(owner->ast_context()), |
| 3574 for_typeof_(false) { | 3674 for_typeof_(false) { |
| (...skipping 792 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4367 } | 4467 } |
| 4368 | 4468 |
| 4369 // Generate a compare and branch. | 4469 // Generate a compare and branch. |
| 4370 CHECK_ALIVE(VisitForValue(clause->label())); | 4470 CHECK_ALIVE(VisitForValue(clause->label())); |
| 4371 HValue* label_value = Pop(); | 4471 HValue* label_value = Pop(); |
| 4372 | 4472 |
| 4373 Type* label_type = clause->label()->bounds().lower; | 4473 Type* label_type = clause->label()->bounds().lower; |
| 4374 Type* combined_type = clause->compare_type(); | 4474 Type* combined_type = clause->compare_type(); |
| 4375 HControlInstruction* compare = BuildCompareInstruction( | 4475 HControlInstruction* compare = BuildCompareInstruction( |
| 4376 Token::EQ_STRICT, tag_value, label_value, tag_type, label_type, | 4476 Token::EQ_STRICT, tag_value, label_value, tag_type, label_type, |
| 4377 combined_type, stmt->tag()->position(), clause->label()->position(), | 4477 combined_type, |
| 4478 ScriptPositionToSourcePosition(stmt->tag()->position()), |
| 4479 ScriptPositionToSourcePosition(clause->label()->position()), |
| 4378 clause->id()); | 4480 clause->id()); |
| 4379 | 4481 |
| 4380 HBasicBlock* next_test_block = graph()->CreateBasicBlock(); | 4482 HBasicBlock* next_test_block = graph()->CreateBasicBlock(); |
| 4381 HBasicBlock* body_block = graph()->CreateBasicBlock(); | 4483 HBasicBlock* body_block = graph()->CreateBasicBlock(); |
| 4382 body_blocks.Add(body_block, zone()); | 4484 body_blocks.Add(body_block, zone()); |
| 4383 compare->SetSuccessorAt(0, body_block); | 4485 compare->SetSuccessorAt(0, body_block); |
| 4384 compare->SetSuccessorAt(1, next_test_block); | 4486 compare->SetSuccessorAt(1, next_test_block); |
| 4385 FinishCurrentBlock(compare); | 4487 FinishCurrentBlock(compare); |
| 4386 | 4488 |
| 4387 set_current_block(body_block); | 4489 set_current_block(body_block); |
| (...skipping 1704 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6092 ASSERT(!HasStackOverflow()); | 6194 ASSERT(!HasStackOverflow()); |
| 6093 ASSERT(current_block() != NULL); | 6195 ASSERT(current_block() != NULL); |
| 6094 ASSERT(current_block()->HasPredecessor()); | 6196 ASSERT(current_block()->HasPredecessor()); |
| 6095 // We don't optimize functions with invalid left-hand sides in | 6197 // We don't optimize functions with invalid left-hand sides in |
| 6096 // assignments, count operations, or for-in. Consequently throw can | 6198 // assignments, count operations, or for-in. Consequently throw can |
| 6097 // currently only occur in an effect context. | 6199 // currently only occur in an effect context. |
| 6098 ASSERT(ast_context()->IsEffect()); | 6200 ASSERT(ast_context()->IsEffect()); |
| 6099 CHECK_ALIVE(VisitForValue(expr->exception())); | 6201 CHECK_ALIVE(VisitForValue(expr->exception())); |
| 6100 | 6202 |
| 6101 HValue* value = environment()->Pop(); | 6203 HValue* value = environment()->Pop(); |
| 6102 if (!FLAG_emit_opt_code_positions) SetSourcePosition(expr->position()); | 6204 if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); |
| 6103 Add<HPushArgument>(value); | 6205 Add<HPushArgument>(value); |
| 6104 Add<HCallRuntime>(isolate()->factory()->empty_string(), | 6206 Add<HCallRuntime>(isolate()->factory()->empty_string(), |
| 6105 Runtime::FunctionForId(Runtime::kThrow), 1); | 6207 Runtime::FunctionForId(Runtime::kThrow), 1); |
| 6106 Add<HSimulate>(expr->id()); | 6208 Add<HSimulate>(expr->id()); |
| 6107 | 6209 |
| 6108 // If the throw definitely exits the function, we can finish with a dummy | 6210 // If the throw definitely exits the function, we can finish with a dummy |
| 6109 // control flow at this point. This is not the case if the throw is inside | 6211 // control flow at this point. This is not the case if the throw is inside |
| 6110 // an inlined function which may be replaced. | 6212 // an inlined function which may be replaced. |
| 6111 if (call_context() == NULL) { | 6213 if (call_context() == NULL) { |
| 6112 FinishExitCurrentBlock(New<HAbnormalExit>()); | 6214 FinishExitCurrentBlock(New<HAbnormalExit>()); |
| (...skipping 912 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7025 int nodes_added = target_shared->ast_node_count(); | 7127 int nodes_added = target_shared->ast_node_count(); |
| 7026 return nodes_added; | 7128 return nodes_added; |
| 7027 } | 7129 } |
| 7028 | 7130 |
| 7029 | 7131 |
| 7030 bool HOptimizedGraphBuilder::TryInline(Handle<JSFunction> target, | 7132 bool HOptimizedGraphBuilder::TryInline(Handle<JSFunction> target, |
| 7031 int arguments_count, | 7133 int arguments_count, |
| 7032 HValue* implicit_return_value, | 7134 HValue* implicit_return_value, |
| 7033 BailoutId ast_id, | 7135 BailoutId ast_id, |
| 7034 BailoutId return_id, | 7136 BailoutId return_id, |
| 7035 InliningKind inlining_kind) { | 7137 InliningKind inlining_kind, |
| 7138 HSourcePosition position) { |
| 7036 int nodes_added = InliningAstSize(target); | 7139 int nodes_added = InliningAstSize(target); |
| 7037 if (nodes_added == kNotInlinable) return false; | 7140 if (nodes_added == kNotInlinable) return false; |
| 7038 | 7141 |
| 7039 Handle<JSFunction> caller = current_info()->closure(); | 7142 Handle<JSFunction> caller = current_info()->closure(); |
| 7040 | 7143 |
| 7041 if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) { | 7144 if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) { |
| 7042 TraceInline(target, caller, "target AST is too large [early]"); | 7145 TraceInline(target, caller, "target AST is too large [early]"); |
| 7043 return false; | 7146 return false; |
| 7044 } | 7147 } |
| 7045 | 7148 |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7157 } | 7260 } |
| 7158 | 7261 |
| 7159 // ---------------------------------------------------------------- | 7262 // ---------------------------------------------------------------- |
| 7160 // After this point, we've made a decision to inline this function (so | 7263 // After this point, we've made a decision to inline this function (so |
| 7161 // TryInline should always return true). | 7264 // TryInline should always return true). |
| 7162 | 7265 |
| 7163 // Type-check the inlined function. | 7266 // Type-check the inlined function. |
| 7164 ASSERT(target_shared->has_deoptimization_support()); | 7267 ASSERT(target_shared->has_deoptimization_support()); |
| 7165 AstTyper::Run(&target_info); | 7268 AstTyper::Run(&target_info); |
| 7166 | 7269 |
| 7270 int function_id = graph()->TraceInlinedFunction(target_shared, position); |
| 7271 |
| 7167 // Save the pending call context. Set up new one for the inlined function. | 7272 // Save the pending call context. Set up new one for the inlined function. |
| 7168 // The function state is new-allocated because we need to delete it | 7273 // The function state is new-allocated because we need to delete it |
| 7169 // in two different places. | 7274 // in two different places. |
| 7170 FunctionState* target_state = new FunctionState( | 7275 FunctionState* target_state = new FunctionState( |
| 7171 this, &target_info, inlining_kind); | 7276 this, &target_info, inlining_kind, function_id); |
| 7172 | 7277 |
| 7173 HConstant* undefined = graph()->GetConstantUndefined(); | 7278 HConstant* undefined = graph()->GetConstantUndefined(); |
| 7174 | 7279 |
| 7175 HEnvironment* inner_env = | 7280 HEnvironment* inner_env = |
| 7176 environment()->CopyForInlining(target, | 7281 environment()->CopyForInlining(target, |
| 7177 arguments_count, | 7282 arguments_count, |
| 7178 function, | 7283 function, |
| 7179 undefined, | 7284 undefined, |
| 7180 function_state()->inlining_kind()); | 7285 function_state()->inlining_kind()); |
| 7181 | 7286 |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7308 return true; | 7413 return true; |
| 7309 } | 7414 } |
| 7310 | 7415 |
| 7311 | 7416 |
| 7312 bool HOptimizedGraphBuilder::TryInlineCall(Call* expr) { | 7417 bool HOptimizedGraphBuilder::TryInlineCall(Call* expr) { |
| 7313 return TryInline(expr->target(), | 7418 return TryInline(expr->target(), |
| 7314 expr->arguments()->length(), | 7419 expr->arguments()->length(), |
| 7315 NULL, | 7420 NULL, |
| 7316 expr->id(), | 7421 expr->id(), |
| 7317 expr->ReturnId(), | 7422 expr->ReturnId(), |
| 7318 NORMAL_RETURN); | 7423 NORMAL_RETURN, |
| 7424 ScriptPositionToSourcePosition(expr->position())); |
| 7319 } | 7425 } |
| 7320 | 7426 |
| 7321 | 7427 |
| 7322 bool HOptimizedGraphBuilder::TryInlineConstruct(CallNew* expr, | 7428 bool HOptimizedGraphBuilder::TryInlineConstruct(CallNew* expr, |
| 7323 HValue* implicit_return_value) { | 7429 HValue* implicit_return_value) { |
| 7324 return TryInline(expr->target(), | 7430 return TryInline(expr->target(), |
| 7325 expr->arguments()->length(), | 7431 expr->arguments()->length(), |
| 7326 implicit_return_value, | 7432 implicit_return_value, |
| 7327 expr->id(), | 7433 expr->id(), |
| 7328 expr->ReturnId(), | 7434 expr->ReturnId(), |
| 7329 CONSTRUCT_CALL_RETURN); | 7435 CONSTRUCT_CALL_RETURN, |
| 7436 ScriptPositionToSourcePosition(expr->position())); |
| 7330 } | 7437 } |
| 7331 | 7438 |
| 7332 | 7439 |
| 7333 bool HOptimizedGraphBuilder::TryInlineGetter(Handle<JSFunction> getter, | 7440 bool HOptimizedGraphBuilder::TryInlineGetter(Handle<JSFunction> getter, |
| 7334 Handle<Map> receiver_map, | 7441 Handle<Map> receiver_map, |
| 7335 BailoutId ast_id, | 7442 BailoutId ast_id, |
| 7336 BailoutId return_id) { | 7443 BailoutId return_id) { |
| 7337 if (TryInlineApiGetter(getter, receiver_map, ast_id)) return true; | 7444 if (TryInlineApiGetter(getter, receiver_map, ast_id)) return true; |
| 7338 return TryInline(getter, | 7445 return TryInline(getter, |
| 7339 0, | 7446 0, |
| 7340 NULL, | 7447 NULL, |
| 7341 ast_id, | 7448 ast_id, |
| 7342 return_id, | 7449 return_id, |
| 7343 GETTER_CALL_RETURN); | 7450 GETTER_CALL_RETURN, |
| 7451 source_position()); |
| 7344 } | 7452 } |
| 7345 | 7453 |
| 7346 | 7454 |
| 7347 bool HOptimizedGraphBuilder::TryInlineSetter(Handle<JSFunction> setter, | 7455 bool HOptimizedGraphBuilder::TryInlineSetter(Handle<JSFunction> setter, |
| 7348 Handle<Map> receiver_map, | 7456 Handle<Map> receiver_map, |
| 7349 BailoutId id, | 7457 BailoutId id, |
| 7350 BailoutId assignment_id, | 7458 BailoutId assignment_id, |
| 7351 HValue* implicit_return_value) { | 7459 HValue* implicit_return_value) { |
| 7352 if (TryInlineApiSetter(setter, receiver_map, id)) return true; | 7460 if (TryInlineApiSetter(setter, receiver_map, id)) return true; |
| 7353 return TryInline(setter, | 7461 return TryInline(setter, |
| 7354 1, | 7462 1, |
| 7355 implicit_return_value, | 7463 implicit_return_value, |
| 7356 id, assignment_id, | 7464 id, assignment_id, |
| 7357 SETTER_CALL_RETURN); | 7465 SETTER_CALL_RETURN, |
| 7466 source_position()); |
| 7358 } | 7467 } |
| 7359 | 7468 |
| 7360 | 7469 |
| 7361 bool HOptimizedGraphBuilder::TryInlineApply(Handle<JSFunction> function, | 7470 bool HOptimizedGraphBuilder::TryInlineApply(Handle<JSFunction> function, |
| 7362 Call* expr, | 7471 Call* expr, |
| 7363 int arguments_count) { | 7472 int arguments_count) { |
| 7364 return TryInline(function, | 7473 return TryInline(function, |
| 7365 arguments_count, | 7474 arguments_count, |
| 7366 NULL, | 7475 NULL, |
| 7367 expr->id(), | 7476 expr->id(), |
| 7368 expr->ReturnId(), | 7477 expr->ReturnId(), |
| 7369 NORMAL_RETURN); | 7478 NORMAL_RETURN, |
| 7479 ScriptPositionToSourcePosition(expr->position())); |
| 7370 } | 7480 } |
| 7371 | 7481 |
| 7372 | 7482 |
| 7373 bool HOptimizedGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr) { | 7483 bool HOptimizedGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr) { |
| 7374 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; | 7484 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; |
| 7375 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); | 7485 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); |
| 7376 switch (id) { | 7486 switch (id) { |
| 7377 case kMathExp: | 7487 case kMathExp: |
| 7378 if (!FLAG_fast_math) break; | 7488 if (!FLAG_fast_math) break; |
| 7379 // Fall through if FLAG_fast_math. | 7489 // Fall through if FLAG_fast_math. |
| (...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7907 | 8017 |
| 7908 HValue* key = NULL; | 8018 HValue* key = NULL; |
| 7909 if (!prop->key()->IsPropertyName()) { | 8019 if (!prop->key()->IsPropertyName()) { |
| 7910 CHECK_ALIVE(VisitForValue(prop->key())); | 8020 CHECK_ALIVE(VisitForValue(prop->key())); |
| 7911 key = Pop(); | 8021 key = Pop(); |
| 7912 } | 8022 } |
| 7913 | 8023 |
| 7914 CHECK_ALIVE(PushLoad(prop, receiver, key)); | 8024 CHECK_ALIVE(PushLoad(prop, receiver, key)); |
| 7915 HValue* function = Pop(); | 8025 HValue* function = Pop(); |
| 7916 | 8026 |
| 8027 if (FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); |
| 8028 |
| 7917 // Push the function under the receiver. | 8029 // Push the function under the receiver. |
| 7918 environment()->SetExpressionStackAt(0, function); | 8030 environment()->SetExpressionStackAt(0, function); |
| 7919 | 8031 |
| 7920 Push(receiver); | 8032 Push(receiver); |
| 7921 | 8033 |
| 7922 if (function->IsConstant() && | 8034 if (function->IsConstant() && |
| 7923 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { | 8035 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { |
| 7924 Handle<JSFunction> known_function = Handle<JSFunction>::cast( | 8036 Handle<JSFunction> known_function = Handle<JSFunction>::cast( |
| 7925 HConstant::cast(function)->handle(isolate())); | 8037 HConstant::cast(function)->handle(isolate())); |
| 7926 expr->set_target(known_function); | 8038 expr->set_target(known_function); |
| (...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8179 TraceInline(target, caller, NULL); | 8291 TraceInline(target, caller, NULL); |
| 8180 } | 8292 } |
| 8181 return inline_ok; | 8293 return inline_ok; |
| 8182 } | 8294 } |
| 8183 | 8295 |
| 8184 | 8296 |
| 8185 void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) { | 8297 void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) { |
| 8186 ASSERT(!HasStackOverflow()); | 8298 ASSERT(!HasStackOverflow()); |
| 8187 ASSERT(current_block() != NULL); | 8299 ASSERT(current_block() != NULL); |
| 8188 ASSERT(current_block()->HasPredecessor()); | 8300 ASSERT(current_block()->HasPredecessor()); |
| 8189 if (!FLAG_emit_opt_code_positions) SetSourcePosition(expr->position()); | 8301 if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); |
| 8190 int argument_count = expr->arguments()->length() + 1; // Plus constructor. | 8302 int argument_count = expr->arguments()->length() + 1; // Plus constructor. |
| 8191 Factory* factory = isolate()->factory(); | 8303 Factory* factory = isolate()->factory(); |
| 8192 | 8304 |
| 8193 // The constructor function is on the stack in the unoptimized code | 8305 // The constructor function is on the stack in the unoptimized code |
| 8194 // during evaluation of the arguments. | 8306 // during evaluation of the arguments. |
| 8195 CHECK_ALIVE(VisitForValue(expr->expression())); | 8307 CHECK_ALIVE(VisitForValue(expr->expression())); |
| 8196 HValue* function = Top(); | 8308 HValue* function = Top(); |
| 8197 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 8309 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
| 8198 | 8310 |
| 8199 if (FLAG_inline_construct && | 8311 if (FLAG_inline_construct && |
| (...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8722 if (key != NULL) Push(key); | 8834 if (key != NULL) Push(key); |
| 8723 Push(value); | 8835 Push(value); |
| 8724 BuildStore(expr, prop, ast_id, return_id); | 8836 BuildStore(expr, prop, ast_id, return_id); |
| 8725 } | 8837 } |
| 8726 | 8838 |
| 8727 | 8839 |
| 8728 void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) { | 8840 void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) { |
| 8729 ASSERT(!HasStackOverflow()); | 8841 ASSERT(!HasStackOverflow()); |
| 8730 ASSERT(current_block() != NULL); | 8842 ASSERT(current_block() != NULL); |
| 8731 ASSERT(current_block()->HasPredecessor()); | 8843 ASSERT(current_block()->HasPredecessor()); |
| 8732 if (!FLAG_emit_opt_code_positions) SetSourcePosition(expr->position()); | 8844 if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); |
| 8733 Expression* target = expr->expression(); | 8845 Expression* target = expr->expression(); |
| 8734 VariableProxy* proxy = target->AsVariableProxy(); | 8846 VariableProxy* proxy = target->AsVariableProxy(); |
| 8735 Property* prop = target->AsProperty(); | 8847 Property* prop = target->AsProperty(); |
| 8736 if (proxy == NULL && prop == NULL) { | 8848 if (proxy == NULL && prop == NULL) { |
| 8737 return Bailout(kInvalidLhsInCountOperation); | 8849 return Bailout(kInvalidLhsInCountOperation); |
| 8738 } | 8850 } |
| 8739 | 8851 |
| 8740 // Match the full code generator stack by simulating an extra stack | 8852 // Match the full code generator stack by simulating an extra stack |
| 8741 // element for postfix operations in a non-effect context. The return | 8853 // element for postfix operations in a non-effect context. The return |
| 8742 // value is ToNumber(input). | 8854 // value is ToNumber(input). |
| (...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9389 void HOptimizedGraphBuilder::VisitArithmeticExpression(BinaryOperation* expr) { | 9501 void HOptimizedGraphBuilder::VisitArithmeticExpression(BinaryOperation* expr) { |
| 9390 CHECK_ALIVE(VisitForValue(expr->left())); | 9502 CHECK_ALIVE(VisitForValue(expr->left())); |
| 9391 CHECK_ALIVE(VisitForValue(expr->right())); | 9503 CHECK_ALIVE(VisitForValue(expr->right())); |
| 9392 SetSourcePosition(expr->position()); | 9504 SetSourcePosition(expr->position()); |
| 9393 HValue* right = Pop(); | 9505 HValue* right = Pop(); |
| 9394 HValue* left = Pop(); | 9506 HValue* left = Pop(); |
| 9395 HValue* result = | 9507 HValue* result = |
| 9396 BuildBinaryOperation(expr, left, right, | 9508 BuildBinaryOperation(expr, left, right, |
| 9397 ast_context()->IsEffect() ? NO_PUSH_BEFORE_SIMULATE | 9509 ast_context()->IsEffect() ? NO_PUSH_BEFORE_SIMULATE |
| 9398 : PUSH_BEFORE_SIMULATE); | 9510 : PUSH_BEFORE_SIMULATE); |
| 9399 if (FLAG_emit_opt_code_positions && result->IsBinaryOperation()) { | 9511 if (FLAG_hydrogen_track_positions && result->IsBinaryOperation()) { |
| 9400 HBinaryOperation::cast(result)->SetOperandPositions( | 9512 HBinaryOperation::cast(result)->SetOperandPositions( |
| 9401 zone(), expr->left()->position(), expr->right()->position()); | 9513 zone(), |
| 9514 ScriptPositionToSourcePosition(expr->left()->position()), |
| 9515 ScriptPositionToSourcePosition(expr->right()->position())); |
| 9402 } | 9516 } |
| 9403 return ast_context()->ReturnValue(result); | 9517 return ast_context()->ReturnValue(result); |
| 9404 } | 9518 } |
| 9405 | 9519 |
| 9406 | 9520 |
| 9407 void HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr, | 9521 void HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr, |
| 9408 Expression* sub_expr, | 9522 Expression* sub_expr, |
| 9409 Handle<String> check) { | 9523 Handle<String> check) { |
| 9410 CHECK_ALIVE(VisitForTypeOf(sub_expr)); | 9524 CHECK_ALIVE(VisitForTypeOf(sub_expr)); |
| 9411 SetSourcePosition(expr->position()); | 9525 SetSourcePosition(expr->position()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 9425 (right->IsConstant() && | 9539 (right->IsConstant() && |
| 9426 HConstant::cast(right)->handle(isolate)->IsBoolean())); | 9540 HConstant::cast(right)->handle(isolate)->IsBoolean())); |
| 9427 } | 9541 } |
| 9428 | 9542 |
| 9429 | 9543 |
| 9430 void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) { | 9544 void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) { |
| 9431 ASSERT(!HasStackOverflow()); | 9545 ASSERT(!HasStackOverflow()); |
| 9432 ASSERT(current_block() != NULL); | 9546 ASSERT(current_block() != NULL); |
| 9433 ASSERT(current_block()->HasPredecessor()); | 9547 ASSERT(current_block()->HasPredecessor()); |
| 9434 | 9548 |
| 9435 if (!FLAG_emit_opt_code_positions) SetSourcePosition(expr->position()); | 9549 if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); |
| 9436 | 9550 |
| 9437 // Check for a few fast cases. The AST visiting behavior must be in sync | 9551 // Check for a few fast cases. The AST visiting behavior must be in sync |
| 9438 // with the full codegen: We don't push both left and right values onto | 9552 // with the full codegen: We don't push both left and right values onto |
| 9439 // the expression stack when one side is a special-case literal. | 9553 // the expression stack when one side is a special-case literal. |
| 9440 Expression* sub_expr = NULL; | 9554 Expression* sub_expr = NULL; |
| 9441 Handle<String> check; | 9555 Handle<String> check; |
| 9442 if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) { | 9556 if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) { |
| 9443 return HandleLiteralCompareTypeof(expr, sub_expr, check); | 9557 return HandleLiteralCompareTypeof(expr, sub_expr, check); |
| 9444 } | 9558 } |
| 9445 if (expr->IsLiteralCompareUndefined(&sub_expr, isolate())) { | 9559 if (expr->IsLiteralCompareUndefined(&sub_expr, isolate())) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 9460 return ast_context()->ReturnControl(instr, expr->id()); | 9574 return ast_context()->ReturnControl(instr, expr->id()); |
| 9461 } | 9575 } |
| 9462 | 9576 |
| 9463 Type* left_type = expr->left()->bounds().lower; | 9577 Type* left_type = expr->left()->bounds().lower; |
| 9464 Type* right_type = expr->right()->bounds().lower; | 9578 Type* right_type = expr->right()->bounds().lower; |
| 9465 Type* combined_type = expr->combined_type(); | 9579 Type* combined_type = expr->combined_type(); |
| 9466 | 9580 |
| 9467 CHECK_ALIVE(VisitForValue(expr->left())); | 9581 CHECK_ALIVE(VisitForValue(expr->left())); |
| 9468 CHECK_ALIVE(VisitForValue(expr->right())); | 9582 CHECK_ALIVE(VisitForValue(expr->right())); |
| 9469 | 9583 |
| 9470 if (FLAG_emit_opt_code_positions) SetSourcePosition(expr->position()); | 9584 if (FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); |
| 9471 | 9585 |
| 9472 HValue* right = Pop(); | 9586 HValue* right = Pop(); |
| 9473 HValue* left = Pop(); | 9587 HValue* left = Pop(); |
| 9474 Token::Value op = expr->op(); | 9588 Token::Value op = expr->op(); |
| 9475 | 9589 |
| 9476 if (IsLiteralCompareBool(isolate(), left, op, right)) { | 9590 if (IsLiteralCompareBool(isolate(), left, op, right)) { |
| 9477 HCompareObjectEqAndBranch* result = | 9591 HCompareObjectEqAndBranch* result = |
| 9478 New<HCompareObjectEqAndBranch>(left, right); | 9592 New<HCompareObjectEqAndBranch>(left, right); |
| 9479 return ast_context()->ReturnControl(result, expr->id()); | 9593 return ast_context()->ReturnControl(result, expr->id()); |
| 9480 } | 9594 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9522 Add<HPushArgument>(left); | 9636 Add<HPushArgument>(left); |
| 9523 Add<HPushArgument>(right); | 9637 Add<HPushArgument>(right); |
| 9524 // TODO(olivf) InvokeFunction produces a check for the parameter count, | 9638 // TODO(olivf) InvokeFunction produces a check for the parameter count, |
| 9525 // even though we are certain to pass the correct number of arguments here. | 9639 // even though we are certain to pass the correct number of arguments here. |
| 9526 HInstruction* result = New<HInvokeFunction>(function, 2); | 9640 HInstruction* result = New<HInvokeFunction>(function, 2); |
| 9527 return ast_context()->ReturnInstruction(result, expr->id()); | 9641 return ast_context()->ReturnInstruction(result, expr->id()); |
| 9528 } | 9642 } |
| 9529 | 9643 |
| 9530 HControlInstruction* compare = BuildCompareInstruction( | 9644 HControlInstruction* compare = BuildCompareInstruction( |
| 9531 op, left, right, left_type, right_type, combined_type, | 9645 op, left, right, left_type, right_type, combined_type, |
| 9532 expr->left()->position(), expr->right()->position(), expr->id()); | 9646 ScriptPositionToSourcePosition(expr->left()->position()), |
| 9647 ScriptPositionToSourcePosition(expr->right()->position()), |
| 9648 expr->id()); |
| 9533 if (compare == NULL) return; // Bailed out. | 9649 if (compare == NULL) return; // Bailed out. |
| 9534 return ast_context()->ReturnControl(compare, expr->id()); | 9650 return ast_context()->ReturnControl(compare, expr->id()); |
| 9535 } | 9651 } |
| 9536 | 9652 |
| 9537 | 9653 |
| 9538 HControlInstruction* HOptimizedGraphBuilder::BuildCompareInstruction( | 9654 HControlInstruction* HOptimizedGraphBuilder::BuildCompareInstruction( |
| 9539 Token::Value op, | 9655 Token::Value op, |
| 9540 HValue* left, | 9656 HValue* left, |
| 9541 HValue* right, | 9657 HValue* right, |
| 9542 Type* left_type, | 9658 Type* left_type, |
| 9543 Type* right_type, | 9659 Type* right_type, |
| 9544 Type* combined_type, | 9660 Type* combined_type, |
| 9545 int left_position, | 9661 HSourcePosition left_position, |
| 9546 int right_position, | 9662 HSourcePosition right_position, |
| 9547 BailoutId bailout_id) { | 9663 BailoutId bailout_id) { |
| 9548 // Cases handled below depend on collected type feedback. They should | 9664 // Cases handled below depend on collected type feedback. They should |
| 9549 // soft deoptimize when there is no type feedback. | 9665 // soft deoptimize when there is no type feedback. |
| 9550 if (combined_type->Is(Type::None())) { | 9666 if (combined_type->Is(Type::None())) { |
| 9551 Add<HDeoptimize>("Insufficient type feedback for combined type " | 9667 Add<HDeoptimize>("Insufficient type feedback for combined type " |
| 9552 "of binary operation", | 9668 "of binary operation", |
| 9553 Deoptimizer::SOFT); | 9669 Deoptimizer::SOFT); |
| 9554 combined_type = left_type = right_type = Type::Any(zone()); | 9670 combined_type = left_type = right_type = Type::Any(zone()); |
| 9555 } | 9671 } |
| 9556 | 9672 |
| 9557 Representation left_rep = Representation::FromType(left_type); | 9673 Representation left_rep = Representation::FromType(left_type); |
| 9558 Representation right_rep = Representation::FromType(right_type); | 9674 Representation right_rep = Representation::FromType(right_type); |
| 9559 Representation combined_rep = Representation::FromType(combined_type); | 9675 Representation combined_rep = Representation::FromType(combined_type); |
| 9560 | 9676 |
| 9561 if (combined_type->Is(Type::Receiver())) { | 9677 if (combined_type->Is(Type::Receiver())) { |
| 9562 if (Token::IsEqualityOp(op)) { | 9678 if (Token::IsEqualityOp(op)) { |
| 9563 // Can we get away with map check and not instance type check? | 9679 // Can we get away with map check and not instance type check? |
| 9564 HValue* operand_to_check = | 9680 HValue* operand_to_check = |
| 9565 left->block()->block_id() < right->block()->block_id() ? left : right; | 9681 left->block()->block_id() < right->block()->block_id() ? left : right; |
| 9566 if (combined_type->IsClass()) { | 9682 if (combined_type->IsClass()) { |
| 9567 Handle<Map> map = combined_type->AsClass(); | 9683 Handle<Map> map = combined_type->AsClass(); |
| 9568 AddCheckMap(operand_to_check, map); | 9684 AddCheckMap(operand_to_check, map); |
| 9569 HCompareObjectEqAndBranch* result = | 9685 HCompareObjectEqAndBranch* result = |
| 9570 New<HCompareObjectEqAndBranch>(left, right); | 9686 New<HCompareObjectEqAndBranch>(left, right); |
| 9571 if (FLAG_emit_opt_code_positions) { | 9687 if (FLAG_hydrogen_track_positions) { |
| 9572 result->set_operand_position(zone(), 0, left_position); | 9688 result->set_operand_position(zone(), 0, left_position); |
| 9573 result->set_operand_position(zone(), 1, right_position); | 9689 result->set_operand_position(zone(), 1, right_position); |
| 9574 } | 9690 } |
| 9575 return result; | 9691 return result; |
| 9576 } else { | 9692 } else { |
| 9577 BuildCheckHeapObject(operand_to_check); | 9693 BuildCheckHeapObject(operand_to_check); |
| 9578 Add<HCheckInstanceType>(operand_to_check, | 9694 Add<HCheckInstanceType>(operand_to_check, |
| 9579 HCheckInstanceType::IS_SPEC_OBJECT); | 9695 HCheckInstanceType::IS_SPEC_OBJECT); |
| 9580 HCompareObjectEqAndBranch* result = | 9696 HCompareObjectEqAndBranch* result = |
| 9581 New<HCompareObjectEqAndBranch>(left, right); | 9697 New<HCompareObjectEqAndBranch>(left, right); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 9612 AddSimulate(bailout_id, REMOVABLE_SIMULATE); | 9728 AddSimulate(bailout_id, REMOVABLE_SIMULATE); |
| 9613 Drop(1); | 9729 Drop(1); |
| 9614 } | 9730 } |
| 9615 // TODO(jkummerow): Can we make this more efficient? | 9731 // TODO(jkummerow): Can we make this more efficient? |
| 9616 HBranch* branch = New<HBranch>(result); | 9732 HBranch* branch = New<HBranch>(result); |
| 9617 return branch; | 9733 return branch; |
| 9618 } else { | 9734 } else { |
| 9619 HCompareNumericAndBranch* result = | 9735 HCompareNumericAndBranch* result = |
| 9620 New<HCompareNumericAndBranch>(left, right, op); | 9736 New<HCompareNumericAndBranch>(left, right, op); |
| 9621 result->set_observed_input_representation(left_rep, right_rep); | 9737 result->set_observed_input_representation(left_rep, right_rep); |
| 9622 if (FLAG_emit_opt_code_positions) { | 9738 if (FLAG_hydrogen_track_positions) { |
| 9623 result->SetOperandPositions(zone(), left_position, right_position); | 9739 result->SetOperandPositions(zone(), left_position, right_position); |
| 9624 } | 9740 } |
| 9625 return result; | 9741 return result; |
| 9626 } | 9742 } |
| 9627 } | 9743 } |
| 9628 } | 9744 } |
| 9629 | 9745 |
| 9630 | 9746 |
| 9631 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, | 9747 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, |
| 9632 Expression* sub_expr, | 9748 Expression* sub_expr, |
| 9633 NilValue nil) { | 9749 NilValue nil) { |
| 9634 ASSERT(!HasStackOverflow()); | 9750 ASSERT(!HasStackOverflow()); |
| 9635 ASSERT(current_block() != NULL); | 9751 ASSERT(current_block() != NULL); |
| 9636 ASSERT(current_block()->HasPredecessor()); | 9752 ASSERT(current_block()->HasPredecessor()); |
| 9637 ASSERT(expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT); | 9753 ASSERT(expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT); |
| 9638 if (!FLAG_emit_opt_code_positions) SetSourcePosition(expr->position()); | 9754 if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); |
| 9639 CHECK_ALIVE(VisitForValue(sub_expr)); | 9755 CHECK_ALIVE(VisitForValue(sub_expr)); |
| 9640 HValue* value = Pop(); | 9756 HValue* value = Pop(); |
| 9641 if (expr->op() == Token::EQ_STRICT) { | 9757 if (expr->op() == Token::EQ_STRICT) { |
| 9642 HConstant* nil_constant = nil == kNullValue | 9758 HConstant* nil_constant = nil == kNullValue |
| 9643 ? graph()->GetConstantNull() | 9759 ? graph()->GetConstantNull() |
| 9644 : graph()->GetConstantUndefined(); | 9760 : graph()->GetConstantUndefined(); |
| 9645 HCompareObjectEqAndBranch* instr = | 9761 HCompareObjectEqAndBranch* instr = |
| 9646 New<HCompareObjectEqAndBranch>(value, nil_constant); | 9762 New<HCompareObjectEqAndBranch>(value, nil_constant); |
| 9647 return ast_context()->ReturnControl(instr, expr->id()); | 9763 return ast_context()->ReturnControl(instr, expr->id()); |
| 9648 } else { | 9764 } else { |
| (...skipping 1216 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10865 PrintTo(&trace); | 10981 PrintTo(&trace); |
| 10866 PrintF("%s", trace.ToCString().get()); | 10982 PrintF("%s", trace.ToCString().get()); |
| 10867 } | 10983 } |
| 10868 | 10984 |
| 10869 | 10985 |
| 10870 void HTracer::TraceCompilation(CompilationInfo* info) { | 10986 void HTracer::TraceCompilation(CompilationInfo* info) { |
| 10871 Tag tag(this, "compilation"); | 10987 Tag tag(this, "compilation"); |
| 10872 if (info->IsOptimizing()) { | 10988 if (info->IsOptimizing()) { |
| 10873 Handle<String> name = info->function()->debug_name(); | 10989 Handle<String> name = info->function()->debug_name(); |
| 10874 PrintStringProperty("name", name->ToCString().get()); | 10990 PrintStringProperty("name", name->ToCString().get()); |
| 10875 PrintStringProperty("method", name->ToCString().get()); | 10991 PrintIndent(); |
| 10992 trace_.Add("method \"%s:%d\"\n", |
| 10993 name->ToCString().get(), |
| 10994 info->optimization_id()); |
| 10876 } else { | 10995 } else { |
| 10877 CodeStub::Major major_key = info->code_stub()->MajorKey(); | 10996 CodeStub::Major major_key = info->code_stub()->MajorKey(); |
| 10878 PrintStringProperty("name", CodeStub::MajorName(major_key, false)); | 10997 PrintStringProperty("name", CodeStub::MajorName(major_key, false)); |
| 10879 PrintStringProperty("method", "stub"); | 10998 PrintStringProperty("method", "stub"); |
| 10880 } | 10999 } |
| 10881 PrintLongProperty("date", static_cast<int64_t>(OS::TimeCurrentMillis())); | 11000 PrintLongProperty("date", static_cast<int64_t>(OS::TimeCurrentMillis())); |
| 10882 } | 11001 } |
| 10883 | 11002 |
| 10884 | 11003 |
| 10885 void HTracer::TraceLithium(const char* name, LChunk* chunk) { | 11004 void HTracer::TraceLithium(const char* name, LChunk* chunk) { |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10979 trace_.Add(" "); | 11098 trace_.Add(" "); |
| 10980 phi->PrintTo(&trace_); | 11099 phi->PrintTo(&trace_); |
| 10981 trace_.Add("\n"); | 11100 trace_.Add("\n"); |
| 10982 } | 11101 } |
| 10983 } | 11102 } |
| 10984 | 11103 |
| 10985 { | 11104 { |
| 10986 Tag HIR_tag(this, "HIR"); | 11105 Tag HIR_tag(this, "HIR"); |
| 10987 for (HInstructionIterator it(current); !it.Done(); it.Advance()) { | 11106 for (HInstructionIterator it(current); !it.Done(); it.Advance()) { |
| 10988 HInstruction* instruction = it.Current(); | 11107 HInstruction* instruction = it.Current(); |
| 10989 int bci = FLAG_emit_opt_code_positions && instruction->has_position() ? | |
| 10990 instruction->position() : 0; | |
| 10991 int uses = instruction->UseCount(); | 11108 int uses = instruction->UseCount(); |
| 10992 PrintIndent(); | 11109 PrintIndent(); |
| 10993 trace_.Add("%d %d ", bci, uses); | 11110 trace_.Add("0 %d ", uses); |
| 10994 instruction->PrintNameTo(&trace_); | 11111 instruction->PrintNameTo(&trace_); |
| 10995 trace_.Add(" "); | 11112 trace_.Add(" "); |
| 10996 instruction->PrintTo(&trace_); | 11113 instruction->PrintTo(&trace_); |
| 11114 if (FLAG_hydrogen_track_positions && |
| 11115 instruction->has_position() && |
| 11116 instruction->position().raw() != 0) { |
| 11117 const HSourcePosition pos = instruction->position(); |
| 11118 trace_.Add(" pos:"); |
| 11119 if (pos.inlining_id() != 0) { |
| 11120 trace_.Add("%d_", pos.inlining_id()); |
| 11121 } |
| 11122 trace_.Add("%d", pos.position()); |
| 11123 } |
| 10997 trace_.Add(" <|@\n"); | 11124 trace_.Add(" <|@\n"); |
| 10998 } | 11125 } |
| 10999 } | 11126 } |
| 11000 | 11127 |
| 11001 | 11128 |
| 11002 if (chunk != NULL) { | 11129 if (chunk != NULL) { |
| 11003 Tag LIR_tag(this, "LIR"); | 11130 Tag LIR_tag(this, "LIR"); |
| 11004 int first_index = current->first_instruction_index(); | 11131 int first_index = current->first_instruction_index(); |
| 11005 int last_index = current->last_instruction_index(); | 11132 int last_index = current->last_instruction_index(); |
| 11006 if (first_index != -1 && last_index != -1) { | 11133 if (first_index != -1 && last_index != -1) { |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11187 if (ShouldProduceTraceOutput()) { | 11314 if (ShouldProduceTraceOutput()) { |
| 11188 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 11315 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 11189 } | 11316 } |
| 11190 | 11317 |
| 11191 #ifdef DEBUG | 11318 #ifdef DEBUG |
| 11192 graph_->Verify(false); // No full verify. | 11319 graph_->Verify(false); // No full verify. |
| 11193 #endif | 11320 #endif |
| 11194 } | 11321 } |
| 11195 | 11322 |
| 11196 } } // namespace v8::internal | 11323 } } // namespace v8::internal |
| OLD | NEW |