| 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 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 | 134 |
| 135 void HBasicBlock::RemovePhi(HPhi* phi) { | 135 void HBasicBlock::RemovePhi(HPhi* phi) { |
| 136 ASSERT(phi->block() == this); | 136 ASSERT(phi->block() == this); |
| 137 ASSERT(phis_.Contains(phi)); | 137 ASSERT(phis_.Contains(phi)); |
| 138 phi->Kill(); | 138 phi->Kill(); |
| 139 phis_.RemoveElement(phi); | 139 phis_.RemoveElement(phi); |
| 140 phi->SetBlock(NULL); | 140 phi->SetBlock(NULL); |
| 141 } | 141 } |
| 142 | 142 |
| 143 | 143 |
| 144 void HBasicBlock::AddInstruction(HInstruction* instr, int position) { | 144 void HBasicBlock::AddInstruction(HInstruction* instr, |
| 145 HSourcePosition position) { |
| 145 ASSERT(!IsStartBlock() || !IsFinished()); | 146 ASSERT(!IsStartBlock() || !IsFinished()); |
| 146 ASSERT(!instr->IsLinked()); | 147 ASSERT(!instr->IsLinked()); |
| 147 ASSERT(!IsFinished()); | 148 ASSERT(!IsFinished()); |
| 148 | 149 |
| 149 if (position != RelocInfo::kNoPosition) { | 150 if (!position.IsUnknown()) { |
| 150 instr->set_position(position); | 151 instr->set_position(position); |
| 151 } | 152 } |
| 152 if (first_ == NULL) { | 153 if (first_ == NULL) { |
| 153 ASSERT(last_environment() != NULL); | 154 ASSERT(last_environment() != NULL); |
| 154 ASSERT(!last_environment()->ast_id().IsNone()); | 155 ASSERT(!last_environment()->ast_id().IsNone()); |
| 155 HBlockEntry* entry = new(zone()) HBlockEntry(); | 156 HBlockEntry* entry = new(zone()) HBlockEntry(); |
| 156 entry->InitializeAsFirst(this); | 157 entry->InitializeAsFirst(this); |
| 157 if (position != RelocInfo::kNoPosition) { | 158 if (!position.IsUnknown()) { |
| 158 entry->set_position(position); | 159 entry->set_position(position); |
| 159 } else { | 160 } else { |
| 160 ASSERT(!FLAG_emit_opt_code_positions || | 161 ASSERT(!FLAG_hydrogen_track_positions || |
| 161 !graph()->info()->IsOptimizing()); | 162 !graph()->info()->IsOptimizing()); |
| 162 } | 163 } |
| 163 first_ = last_ = entry; | 164 first_ = last_ = entry; |
| 164 } | 165 } |
| 165 instr->InsertAfter(last_); | 166 instr->InsertAfter(last_); |
| 166 } | 167 } |
| 167 | 168 |
| 168 | 169 |
| 169 HPhi* HBasicBlock::AddNewPhi(int merged_index) { | 170 HPhi* HBasicBlock::AddNewPhi(int merged_index) { |
| 170 if (graph()->IsInsideNoSideEffectsScope()) { | 171 if (graph()->IsInsideNoSideEffectsScope()) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 !it.Done(); | 204 !it.Done(); |
| 204 it.Advance()) { | 205 it.Advance()) { |
| 205 int index = it.Current(); | 206 int index = it.Current(); |
| 206 instr->AddAssignedValue(index, environment->Lookup(index)); | 207 instr->AddAssignedValue(index, environment->Lookup(index)); |
| 207 } | 208 } |
| 208 environment->ClearHistory(); | 209 environment->ClearHistory(); |
| 209 return instr; | 210 return instr; |
| 210 } | 211 } |
| 211 | 212 |
| 212 | 213 |
| 213 void HBasicBlock::Finish(HControlInstruction* end, int position) { | 214 void HBasicBlock::Finish(HControlInstruction* end, HSourcePosition position) { |
| 214 ASSERT(!IsFinished()); | 215 ASSERT(!IsFinished()); |
| 215 AddInstruction(end, position); | 216 AddInstruction(end, position); |
| 216 end_ = end; | 217 end_ = end; |
| 217 for (HSuccessorIterator it(end); !it.Done(); it.Advance()) { | 218 for (HSuccessorIterator it(end); !it.Done(); it.Advance()) { |
| 218 it.Current()->RegisterPredecessor(this); | 219 it.Current()->RegisterPredecessor(this); |
| 219 } | 220 } |
| 220 } | 221 } |
| 221 | 222 |
| 222 | 223 |
| 223 void HBasicBlock::Goto(HBasicBlock* block, | 224 void HBasicBlock::Goto(HBasicBlock* block, |
| 224 int position, | 225 HSourcePosition position, |
| 225 FunctionState* state, | 226 FunctionState* state, |
| 226 bool add_simulate) { | 227 bool add_simulate) { |
| 227 bool drop_extra = state != NULL && | 228 bool drop_extra = state != NULL && |
| 228 state->inlining_kind() == DROP_EXTRA_ON_RETURN; | 229 state->inlining_kind() == DROP_EXTRA_ON_RETURN; |
| 229 | 230 |
| 230 if (block->IsInlineReturnTarget()) { | 231 if (block->IsInlineReturnTarget()) { |
| 231 HEnvironment* env = last_environment(); | 232 HEnvironment* env = last_environment(); |
| 232 int argument_count = env->arguments_environment()->parameter_count(); | 233 int argument_count = env->arguments_environment()->parameter_count(); |
| 233 AddInstruction(new(zone()) | 234 AddInstruction(new(zone()) |
| 234 HLeaveInlined(state->entry(), argument_count), | 235 HLeaveInlined(state->entry(), argument_count), |
| 235 position); | 236 position); |
| 236 UpdateEnvironment(last_environment()->DiscardInlined(drop_extra)); | 237 UpdateEnvironment(last_environment()->DiscardInlined(drop_extra)); |
| 237 } | 238 } |
| 238 | 239 |
| 239 if (add_simulate) AddNewSimulate(BailoutId::None(), position); | 240 if (add_simulate) AddNewSimulate(BailoutId::None(), position); |
| 240 HGoto* instr = new(zone()) HGoto(block); | 241 HGoto* instr = new(zone()) HGoto(block); |
| 241 Finish(instr, position); | 242 Finish(instr, position); |
| 242 } | 243 } |
| 243 | 244 |
| 244 | 245 |
| 245 void HBasicBlock::AddLeaveInlined(HValue* return_value, | 246 void HBasicBlock::AddLeaveInlined(HValue* return_value, |
| 246 FunctionState* state, | 247 FunctionState* state, |
| 247 int position) { | 248 HSourcePosition position) { |
| 248 HBasicBlock* target = state->function_return(); | 249 HBasicBlock* target = state->function_return(); |
| 249 bool drop_extra = state->inlining_kind() == DROP_EXTRA_ON_RETURN; | 250 bool drop_extra = state->inlining_kind() == DROP_EXTRA_ON_RETURN; |
| 250 | 251 |
| 251 ASSERT(target->IsInlineReturnTarget()); | 252 ASSERT(target->IsInlineReturnTarget()); |
| 252 ASSERT(return_value != NULL); | 253 ASSERT(return_value != NULL); |
| 253 HEnvironment* env = last_environment(); | 254 HEnvironment* env = last_environment(); |
| 254 int argument_count = env->arguments_environment()->parameter_count(); | 255 int argument_count = env->arguments_environment()->parameter_count(); |
| 255 AddInstruction(new(zone()) HLeaveInlined(state->entry(), argument_count), | 256 AddInstruction(new(zone()) HLeaveInlined(state->entry(), argument_count), |
| 256 position); | 257 position); |
| 257 UpdateEnvironment(last_environment()->DiscardInlined(drop_extra)); | 258 UpdateEnvironment(last_environment()->DiscardInlined(drop_extra)); |
| (...skipping 896 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1154 CompilationPhase phase("H_Block building", info_); | 1155 CompilationPhase phase("H_Block building", info_); |
| 1155 set_current_block(graph()->entry_block()); | 1156 set_current_block(graph()->entry_block()); |
| 1156 if (!BuildGraph()) return NULL; | 1157 if (!BuildGraph()) return NULL; |
| 1157 graph()->FinalizeUniqueness(); | 1158 graph()->FinalizeUniqueness(); |
| 1158 return graph_; | 1159 return graph_; |
| 1159 } | 1160 } |
| 1160 | 1161 |
| 1161 | 1162 |
| 1162 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { | 1163 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { |
| 1163 ASSERT(current_block() != NULL); | 1164 ASSERT(current_block() != NULL); |
| 1164 ASSERT(!FLAG_emit_opt_code_positions || | 1165 ASSERT(!FLAG_hydrogen_track_positions || |
| 1165 position_ != RelocInfo::kNoPosition || !info_->IsOptimizing()); | 1166 !position_.IsUnknown() || |
| 1166 current_block()->AddInstruction(instr, position_); | 1167 !info_->IsOptimizing()); |
| 1168 current_block()->AddInstruction(instr, source_position()); |
| 1167 if (graph()->IsInsideNoSideEffectsScope()) { | 1169 if (graph()->IsInsideNoSideEffectsScope()) { |
| 1168 instr->SetFlag(HValue::kHasNoObservableSideEffects); | 1170 instr->SetFlag(HValue::kHasNoObservableSideEffects); |
| 1169 } | 1171 } |
| 1170 return instr; | 1172 return instr; |
| 1171 } | 1173 } |
| 1172 | 1174 |
| 1173 | 1175 |
| 1174 void HGraphBuilder::FinishCurrentBlock(HControlInstruction* last) { | 1176 void HGraphBuilder::FinishCurrentBlock(HControlInstruction* last) { |
| 1175 ASSERT(!FLAG_emit_opt_code_positions || !info_->IsOptimizing() || | 1177 ASSERT(!FLAG_hydrogen_track_positions || |
| 1176 position_ != RelocInfo::kNoPosition); | 1178 !info_->IsOptimizing() || |
| 1177 current_block()->Finish(last, position_); | 1179 !position_.IsUnknown()); |
| 1180 current_block()->Finish(last, source_position()); |
| 1178 if (last->IsReturn() || last->IsAbnormalExit()) { | 1181 if (last->IsReturn() || last->IsAbnormalExit()) { |
| 1179 set_current_block(NULL); | 1182 set_current_block(NULL); |
| 1180 } | 1183 } |
| 1181 } | 1184 } |
| 1182 | 1185 |
| 1183 | 1186 |
| 1184 void HGraphBuilder::FinishExitCurrentBlock(HControlInstruction* instruction) { | 1187 void HGraphBuilder::FinishExitCurrentBlock(HControlInstruction* instruction) { |
| 1185 ASSERT(!FLAG_emit_opt_code_positions || !info_->IsOptimizing() || | 1188 ASSERT(!FLAG_hydrogen_track_positions || !info_->IsOptimizing() || |
| 1186 position_ != RelocInfo::kNoPosition); | 1189 !position_.IsUnknown()); |
| 1187 current_block()->FinishExit(instruction, position_); | 1190 current_block()->FinishExit(instruction, source_position()); |
| 1188 if (instruction->IsReturn() || instruction->IsAbnormalExit()) { | 1191 if (instruction->IsReturn() || instruction->IsAbnormalExit()) { |
| 1189 set_current_block(NULL); | 1192 set_current_block(NULL); |
| 1190 } | 1193 } |
| 1191 } | 1194 } |
| 1192 | 1195 |
| 1193 | 1196 |
| 1194 void HGraphBuilder::AddIncrementCounter(StatsCounter* counter) { | 1197 void HGraphBuilder::AddIncrementCounter(StatsCounter* counter) { |
| 1195 if (FLAG_native_code_counters && counter->Enabled()) { | 1198 if (FLAG_native_code_counters && counter->Enabled()) { |
| 1196 HValue* reference = Add<HConstant>(ExternalReference(counter)); | 1199 HValue* reference = Add<HConstant>(ExternalReference(counter)); |
| 1197 HValue* old_value = Add<HLoadNamedField>(reference, | 1200 HValue* old_value = Add<HLoadNamedField>(reference, |
| 1198 HObjectAccess::ForCounter()); | 1201 HObjectAccess::ForCounter()); |
| 1199 HValue* new_value = AddUncasted<HAdd>(old_value, graph()->GetConstant1()); | 1202 HValue* new_value = AddUncasted<HAdd>(old_value, graph()->GetConstant1()); |
| 1200 new_value->ClearFlag(HValue::kCanOverflow); // Ignore counter overflow | 1203 new_value->ClearFlag(HValue::kCanOverflow); // Ignore counter overflow |
| 1201 Add<HStoreNamedField>(reference, HObjectAccess::ForCounter(), | 1204 Add<HStoreNamedField>(reference, HObjectAccess::ForCounter(), |
| 1202 new_value); | 1205 new_value); |
| 1203 } | 1206 } |
| 1204 } | 1207 } |
| 1205 | 1208 |
| 1206 | 1209 |
| 1207 void HGraphBuilder::AddSimulate(BailoutId id, | 1210 void HGraphBuilder::AddSimulate(BailoutId id, |
| 1208 RemovableSimulate removable) { | 1211 RemovableSimulate removable) { |
| 1209 ASSERT(current_block() != NULL); | 1212 ASSERT(current_block() != NULL); |
| 1210 ASSERT(!graph()->IsInsideNoSideEffectsScope()); | 1213 ASSERT(!graph()->IsInsideNoSideEffectsScope()); |
| 1211 current_block()->AddNewSimulate(id, position_, removable); | 1214 current_block()->AddNewSimulate(id, source_position(), removable); |
| 1212 } | 1215 } |
| 1213 | 1216 |
| 1214 | 1217 |
| 1215 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { | 1218 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { |
| 1216 HBasicBlock* b = graph()->CreateBasicBlock(); | 1219 HBasicBlock* b = graph()->CreateBasicBlock(); |
| 1217 b->SetInitialEnvironment(env); | 1220 b->SetInitialEnvironment(env); |
| 1218 return b; | 1221 return b; |
| 1219 } | 1222 } |
| 1220 | 1223 |
| 1221 | 1224 |
| (...skipping 1660 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2882 HValue* builtins = Add<HLoadNamedField>(global_object, access); | 2885 HValue* builtins = Add<HLoadNamedField>(global_object, access); |
| 2883 HObjectAccess function_access = HObjectAccess::ForJSObjectOffset( | 2886 HObjectAccess function_access = HObjectAccess::ForJSObjectOffset( |
| 2884 JSBuiltinsObject::OffsetOfFunctionWithId(builtin)); | 2887 JSBuiltinsObject::OffsetOfFunctionWithId(builtin)); |
| 2885 return Add<HLoadNamedField>(builtins, function_access); | 2888 return Add<HLoadNamedField>(builtins, function_access); |
| 2886 } | 2889 } |
| 2887 | 2890 |
| 2888 | 2891 |
| 2889 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info) | 2892 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info) |
| 2890 : HGraphBuilder(info), | 2893 : HGraphBuilder(info), |
| 2891 function_state_(NULL), | 2894 function_state_(NULL), |
| 2892 initial_function_state_(this, info, NORMAL_RETURN), | 2895 initial_function_state_(this, info, NORMAL_RETURN, 0), |
| 2893 ast_context_(NULL), | 2896 ast_context_(NULL), |
| 2894 break_scope_(NULL), | 2897 break_scope_(NULL), |
| 2895 inlined_count_(0), | 2898 inlined_count_(0), |
| 2896 globals_(10, info->zone()), | 2899 globals_(10, info->zone()), |
| 2897 inline_bailout_(false), | 2900 inline_bailout_(false), |
| 2898 osr_(new(info->zone()) HOsrBuilder(this)) { | 2901 osr_(new(info->zone()) HOsrBuilder(this)) { |
| 2899 // This is not initialized in the initializer list because the | 2902 // This is not initialized in the initializer list because the |
| 2900 // constructor for the initial state relies on function_state_ == NULL | 2903 // constructor for the initial state relies on function_state_ == NULL |
| 2901 // to know it's the initial state. | 2904 // to know it's the initial state. |
| 2902 function_state_= &initial_function_state_; | 2905 function_state_= &initial_function_state_; |
| 2903 InitializeAstVisitor(info->zone()); | 2906 InitializeAstVisitor(info->zone()); |
| 2904 if (FLAG_emit_opt_code_positions) { | 2907 if (FLAG_hydrogen_track_positions) { |
| 2905 SetSourcePosition(info->shared_info()->start_position()); | 2908 SetSourcePosition(info->shared_info()->start_position()); |
| 2906 } | 2909 } |
| 2907 } | 2910 } |
| 2908 | 2911 |
| 2909 | 2912 |
| 2910 HBasicBlock* HOptimizedGraphBuilder::CreateJoin(HBasicBlock* first, | 2913 HBasicBlock* HOptimizedGraphBuilder::CreateJoin(HBasicBlock* first, |
| 2911 HBasicBlock* second, | 2914 HBasicBlock* second, |
| 2912 BailoutId join_id) { | 2915 BailoutId join_id) { |
| 2913 if (first == NULL) { | 2916 if (first == NULL) { |
| 2914 return second; | 2917 return second; |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2963 | 2966 |
| 2964 HBasicBlock* HOptimizedGraphBuilder::BuildLoopEntry( | 2967 HBasicBlock* HOptimizedGraphBuilder::BuildLoopEntry( |
| 2965 IterationStatement* statement) { | 2968 IterationStatement* statement) { |
| 2966 HBasicBlock* loop_entry = osr()->HasOsrEntryAt(statement) | 2969 HBasicBlock* loop_entry = osr()->HasOsrEntryAt(statement) |
| 2967 ? osr()->BuildOsrLoopEntry(statement) | 2970 ? osr()->BuildOsrLoopEntry(statement) |
| 2968 : BuildLoopEntry(); | 2971 : BuildLoopEntry(); |
| 2969 return loop_entry; | 2972 return loop_entry; |
| 2970 } | 2973 } |
| 2971 | 2974 |
| 2972 | 2975 |
| 2973 void HBasicBlock::FinishExit(HControlInstruction* instruction, int position) { | 2976 void HBasicBlock::FinishExit(HControlInstruction* instruction, |
| 2977 HSourcePosition position) { |
| 2974 Finish(instruction, position); | 2978 Finish(instruction, position); |
| 2975 ClearEnvironment(); | 2979 ClearEnvironment(); |
| 2976 } | 2980 } |
| 2977 | 2981 |
| 2978 | 2982 |
| 2979 HGraph::HGraph(CompilationInfo* info) | 2983 HGraph::HGraph(CompilationInfo* info) |
| 2980 : isolate_(info->isolate()), | 2984 : isolate_(info->isolate()), |
| 2981 next_block_id_(0), | 2985 next_block_id_(0), |
| 2982 entry_block_(NULL), | 2986 entry_block_(NULL), |
| 2983 blocks_(8, info->zone()), | 2987 blocks_(8, info->zone()), |
| 2984 values_(16, info->zone()), | 2988 values_(16, info->zone()), |
| 2985 phi_list_(NULL), | 2989 phi_list_(NULL), |
| 2986 uint32_instructions_(NULL), | 2990 uint32_instructions_(NULL), |
| 2987 osr_(NULL), | 2991 osr_(NULL), |
| 2988 info_(info), | 2992 info_(info), |
| 2989 zone_(info->zone()), | 2993 zone_(info->zone()), |
| 2990 is_recursive_(false), | 2994 is_recursive_(false), |
| 2991 use_optimistic_licm_(false), | 2995 use_optimistic_licm_(false), |
| 2992 depends_on_empty_array_proto_elements_(false), | 2996 depends_on_empty_array_proto_elements_(false), |
| 2993 type_change_checksum_(0), | 2997 type_change_checksum_(0), |
| 2994 maximum_environment_size_(0), | 2998 maximum_environment_size_(0), |
| 2995 no_side_effects_scope_count_(0), | 2999 no_side_effects_scope_count_(0), |
| 2996 disallow_adding_new_values_(false) { | 3000 disallow_adding_new_values_(false), |
| 3001 next_inline_id_(0), |
| 3002 inlined_functions_(5, info->zone()) { |
| 2997 if (info->IsStub()) { | 3003 if (info->IsStub()) { |
| 2998 HydrogenCodeStub* stub = info->code_stub(); | 3004 HydrogenCodeStub* stub = info->code_stub(); |
| 2999 CodeStubInterfaceDescriptor* descriptor = | 3005 CodeStubInterfaceDescriptor* descriptor = |
| 3000 stub->GetInterfaceDescriptor(isolate_); | 3006 stub->GetInterfaceDescriptor(isolate_); |
| 3001 start_environment_ = | 3007 start_environment_ = |
| 3002 new(zone_) HEnvironment(zone_, descriptor->environment_length()); | 3008 new(zone_) HEnvironment(zone_, descriptor->environment_length()); |
| 3003 } else { | 3009 } else { |
| 3010 TraceInlinedFunction(info->shared_info(), HSourcePosition::Unknown()); |
| 3004 start_environment_ = | 3011 start_environment_ = |
| 3005 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); | 3012 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); |
| 3006 } | 3013 } |
| 3007 start_environment_->set_ast_id(BailoutId::FunctionEntry()); | 3014 start_environment_->set_ast_id(BailoutId::FunctionEntry()); |
| 3008 entry_block_ = CreateBasicBlock(); | 3015 entry_block_ = CreateBasicBlock(); |
| 3009 entry_block_->SetInitialEnvironment(start_environment_); | 3016 entry_block_->SetInitialEnvironment(start_environment_); |
| 3010 } | 3017 } |
| 3011 | 3018 |
| 3012 | 3019 |
| 3013 HBasicBlock* HGraph::CreateBasicBlock() { | 3020 HBasicBlock* HGraph::CreateBasicBlock() { |
| 3014 HBasicBlock* result = new(zone()) HBasicBlock(this); | 3021 HBasicBlock* result = new(zone()) HBasicBlock(this); |
| 3015 blocks_.Add(result, zone()); | 3022 blocks_.Add(result, zone()); |
| 3016 return result; | 3023 return result; |
| 3017 } | 3024 } |
| 3018 | 3025 |
| 3019 | 3026 |
| 3020 void HGraph::FinalizeUniqueness() { | 3027 void HGraph::FinalizeUniqueness() { |
| 3021 DisallowHeapAllocation no_gc; | 3028 DisallowHeapAllocation no_gc; |
| 3022 ASSERT(!OptimizingCompilerThread::IsOptimizerThread(isolate())); | 3029 ASSERT(!OptimizingCompilerThread::IsOptimizerThread(isolate())); |
| 3023 for (int i = 0; i < blocks()->length(); ++i) { | 3030 for (int i = 0; i < blocks()->length(); ++i) { |
| 3024 for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) { | 3031 for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) { |
| 3025 it.Current()->FinalizeUniqueness(); | 3032 it.Current()->FinalizeUniqueness(); |
| 3026 } | 3033 } |
| 3027 } | 3034 } |
| 3028 } | 3035 } |
| 3029 | 3036 |
| 3030 | 3037 |
| 3038 int HGraph::TraceInlinedFunction( |
| 3039 Handle<SharedFunctionInfo> shared, |
| 3040 HSourcePosition position) { |
| 3041 if (!FLAG_hydrogen_track_positions) { |
| 3042 return 0; |
| 3043 } |
| 3044 |
| 3045 int id = 0; |
| 3046 for (; id < inlined_functions_.length(); id++) { |
| 3047 if (inlined_functions_[id].shared().is_identical_to(shared)) { |
| 3048 break; |
| 3049 } |
| 3050 } |
| 3051 |
| 3052 if (id == inlined_functions_.length()) { |
| 3053 inlined_functions_.Add(InlinedFunctionInfo(shared), zone()); |
| 3054 |
| 3055 if (!shared->script()->IsUndefined()) { |
| 3056 Handle<Script> script(Script::cast(shared->script())); |
| 3057 if (!script->source()->IsUndefined()) { |
| 3058 CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer()); |
| 3059 PrintF(tracing_scope.file(), |
| 3060 "--- FUNCTION SOURCE (%s) id{%d,%d} ---\n", |
| 3061 shared->DebugName()->ToCString().get(), |
| 3062 info()->optimization_id(), |
| 3063 id); |
| 3064 |
| 3065 { |
| 3066 ConsStringIteratorOp op; |
| 3067 StringCharacterStream stream(String::cast(script->source()), |
| 3068 &op, |
| 3069 shared->start_position()); |
| 3070 // fun->end_position() points to the last character in the stream. We |
| 3071 // need to compensate by adding one to calculate the length. |
| 3072 int source_len = |
| 3073 shared->end_position() - shared->start_position() + 1; |
| 3074 for (int i = 0; i < source_len; i++) { |
| 3075 if (stream.HasMore()) { |
| 3076 PrintF(tracing_scope.file(), "%c", stream.GetNext()); |
| 3077 } |
| 3078 } |
| 3079 } |
| 3080 |
| 3081 PrintF(tracing_scope.file(), "\n--- END ---\n"); |
| 3082 } |
| 3083 } |
| 3084 } |
| 3085 |
| 3086 int inline_id = next_inline_id_++; |
| 3087 |
| 3088 if (inline_id != 0) { |
| 3089 CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer()); |
| 3090 PrintF(tracing_scope.file(), "INLINE (%s) id{%d,%d} AS %d AT ", |
| 3091 shared->DebugName()->ToCString().get(), |
| 3092 info()->optimization_id(), |
| 3093 id, |
| 3094 inline_id); |
| 3095 position.PrintTo(tracing_scope.file()); |
| 3096 PrintF(tracing_scope.file(), "\n"); |
| 3097 } |
| 3098 |
| 3099 return inline_id; |
| 3100 } |
| 3101 |
| 3102 |
| 3103 int HGraph::SourcePositionToScriptPosition(HSourcePosition pos) { |
| 3104 if (!FLAG_hydrogen_track_positions || pos.IsUnknown()) { |
| 3105 return pos.raw(); |
| 3106 } |
| 3107 |
| 3108 return inlined_functions_[pos.inlining_id()].start_position() + |
| 3109 pos.position(); |
| 3110 } |
| 3111 |
| 3112 |
| 3031 // Block ordering was implemented with two mutually recursive methods, | 3113 // Block ordering was implemented with two mutually recursive methods, |
| 3032 // HGraph::Postorder and HGraph::PostorderLoopBlocks. | 3114 // HGraph::Postorder and HGraph::PostorderLoopBlocks. |
| 3033 // The recursion could lead to stack overflow so the algorithm has been | 3115 // The recursion could lead to stack overflow so the algorithm has been |
| 3034 // implemented iteratively. | 3116 // implemented iteratively. |
| 3035 // At a high level the algorithm looks like this: | 3117 // At a high level the algorithm looks like this: |
| 3036 // | 3118 // |
| 3037 // Postorder(block, loop_header) : { | 3119 // Postorder(block, loop_header) : { |
| 3038 // if (block has already been visited or is of another loop) return; | 3120 // if (block has already been visited or is of another loop) return; |
| 3039 // mark block as visited; | 3121 // mark block as visited; |
| 3040 // if (block is a loop header) { | 3122 // if (block is a loop header) { |
| (...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3399 phi_list_->Add(phi, zone()); | 3481 phi_list_->Add(phi, zone()); |
| 3400 } | 3482 } |
| 3401 } | 3483 } |
| 3402 } | 3484 } |
| 3403 | 3485 |
| 3404 | 3486 |
| 3405 // Implementation of utility class to encapsulate the translation state for | 3487 // Implementation of utility class to encapsulate the translation state for |
| 3406 // a (possibly inlined) function. | 3488 // a (possibly inlined) function. |
| 3407 FunctionState::FunctionState(HOptimizedGraphBuilder* owner, | 3489 FunctionState::FunctionState(HOptimizedGraphBuilder* owner, |
| 3408 CompilationInfo* info, | 3490 CompilationInfo* info, |
| 3409 InliningKind inlining_kind) | 3491 InliningKind inlining_kind, |
| 3492 int inlining_id) |
| 3410 : owner_(owner), | 3493 : owner_(owner), |
| 3411 compilation_info_(info), | 3494 compilation_info_(info), |
| 3412 call_context_(NULL), | 3495 call_context_(NULL), |
| 3413 inlining_kind_(inlining_kind), | 3496 inlining_kind_(inlining_kind), |
| 3414 function_return_(NULL), | 3497 function_return_(NULL), |
| 3415 test_context_(NULL), | 3498 test_context_(NULL), |
| 3416 entry_(NULL), | 3499 entry_(NULL), |
| 3417 arguments_object_(NULL), | 3500 arguments_object_(NULL), |
| 3418 arguments_elements_(NULL), | 3501 arguments_elements_(NULL), |
| 3502 inlining_id_(inlining_id), |
| 3503 outer_source_position_(HSourcePosition::Unknown()), |
| 3419 outer_(owner->function_state()) { | 3504 outer_(owner->function_state()) { |
| 3420 if (outer_ != NULL) { | 3505 if (outer_ != NULL) { |
| 3421 // State for an inline function. | 3506 // State for an inline function. |
| 3422 if (owner->ast_context()->IsTest()) { | 3507 if (owner->ast_context()->IsTest()) { |
| 3423 HBasicBlock* if_true = owner->graph()->CreateBasicBlock(); | 3508 HBasicBlock* if_true = owner->graph()->CreateBasicBlock(); |
| 3424 HBasicBlock* if_false = owner->graph()->CreateBasicBlock(); | 3509 HBasicBlock* if_false = owner->graph()->CreateBasicBlock(); |
| 3425 if_true->MarkAsInlineReturnTarget(owner->current_block()); | 3510 if_true->MarkAsInlineReturnTarget(owner->current_block()); |
| 3426 if_false->MarkAsInlineReturnTarget(owner->current_block()); | 3511 if_false->MarkAsInlineReturnTarget(owner->current_block()); |
| 3427 TestContext* outer_test_context = TestContext::cast(owner->ast_context()); | 3512 TestContext* outer_test_context = TestContext::cast(owner->ast_context()); |
| 3428 Expression* cond = outer_test_context->condition(); | 3513 Expression* cond = outer_test_context->condition(); |
| 3429 // The AstContext constructor pushed on the context stack. This newed | 3514 // The AstContext constructor pushed on the context stack. This newed |
| 3430 // instance is the reason that AstContext can't be BASE_EMBEDDED. | 3515 // instance is the reason that AstContext can't be BASE_EMBEDDED. |
| 3431 test_context_ = new TestContext(owner, cond, if_true, if_false); | 3516 test_context_ = new TestContext(owner, cond, if_true, if_false); |
| 3432 } else { | 3517 } else { |
| 3433 function_return_ = owner->graph()->CreateBasicBlock(); | 3518 function_return_ = owner->graph()->CreateBasicBlock(); |
| 3434 function_return()->MarkAsInlineReturnTarget(owner->current_block()); | 3519 function_return()->MarkAsInlineReturnTarget(owner->current_block()); |
| 3435 } | 3520 } |
| 3436 // Set this after possibly allocating a new TestContext above. | 3521 // Set this after possibly allocating a new TestContext above. |
| 3437 call_context_ = owner->ast_context(); | 3522 call_context_ = owner->ast_context(); |
| 3438 } | 3523 } |
| 3439 | 3524 |
| 3440 // Push on the state stack. | 3525 // Push on the state stack. |
| 3441 owner->set_function_state(this); | 3526 owner->set_function_state(this); |
| 3527 |
| 3528 if (FLAG_hydrogen_track_positions) { |
| 3529 outer_source_position_ = owner->source_position(); |
| 3530 owner->EnterInlinedSource( |
| 3531 info->shared_info()->start_position(), |
| 3532 inlining_id); |
| 3533 owner->SetSourcePosition(info->shared_info()->start_position()); |
| 3534 } |
| 3442 } | 3535 } |
| 3443 | 3536 |
| 3444 | 3537 |
| 3445 FunctionState::~FunctionState() { | 3538 FunctionState::~FunctionState() { |
| 3446 delete test_context_; | 3539 delete test_context_; |
| 3447 owner_->set_function_state(outer_); | 3540 owner_->set_function_state(outer_); |
| 3541 |
| 3542 if (FLAG_hydrogen_track_positions) { |
| 3543 owner_->set_source_position(outer_source_position_); |
| 3544 owner_->EnterInlinedSource( |
| 3545 outer_->compilation_info()->shared_info()->start_position(), |
| 3546 outer_->inlining_id()); |
| 3547 } |
| 3448 } | 3548 } |
| 3449 | 3549 |
| 3450 | 3550 |
| 3451 // Implementation of utility classes to represent an expression's context in | 3551 // Implementation of utility classes to represent an expression's context in |
| 3452 // the AST. | 3552 // the AST. |
| 3453 AstContext::AstContext(HOptimizedGraphBuilder* owner, Expression::Context kind) | 3553 AstContext::AstContext(HOptimizedGraphBuilder* owner, Expression::Context kind) |
| 3454 : owner_(owner), | 3554 : owner_(owner), |
| 3455 kind_(kind), | 3555 kind_(kind), |
| 3456 outer_(owner->ast_context()), | 3556 outer_(owner->ast_context()), |
| 3457 for_typeof_(false) { | 3557 for_typeof_(false) { |
| (...skipping 786 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4244 } | 4344 } |
| 4245 | 4345 |
| 4246 // Generate a compare and branch. | 4346 // Generate a compare and branch. |
| 4247 CHECK_ALIVE(VisitForValue(clause->label())); | 4347 CHECK_ALIVE(VisitForValue(clause->label())); |
| 4248 HValue* label_value = Pop(); | 4348 HValue* label_value = Pop(); |
| 4249 | 4349 |
| 4250 Type* label_type = clause->label()->bounds().lower; | 4350 Type* label_type = clause->label()->bounds().lower; |
| 4251 Type* combined_type = clause->compare_type(); | 4351 Type* combined_type = clause->compare_type(); |
| 4252 HControlInstruction* compare = BuildCompareInstruction( | 4352 HControlInstruction* compare = BuildCompareInstruction( |
| 4253 Token::EQ_STRICT, tag_value, label_value, tag_type, label_type, | 4353 Token::EQ_STRICT, tag_value, label_value, tag_type, label_type, |
| 4254 combined_type, stmt->tag()->position(), clause->label()->position(), | 4354 combined_type, |
| 4355 ScriptPositionToSourcePosition(stmt->tag()->position()), |
| 4356 ScriptPositionToSourcePosition(clause->label()->position()), |
| 4255 clause->id()); | 4357 clause->id()); |
| 4256 | 4358 |
| 4257 HBasicBlock* next_test_block = graph()->CreateBasicBlock(); | 4359 HBasicBlock* next_test_block = graph()->CreateBasicBlock(); |
| 4258 HBasicBlock* body_block = graph()->CreateBasicBlock(); | 4360 HBasicBlock* body_block = graph()->CreateBasicBlock(); |
| 4259 body_blocks.Add(body_block, zone()); | 4361 body_blocks.Add(body_block, zone()); |
| 4260 compare->SetSuccessorAt(0, body_block); | 4362 compare->SetSuccessorAt(0, body_block); |
| 4261 compare->SetSuccessorAt(1, next_test_block); | 4363 compare->SetSuccessorAt(1, next_test_block); |
| 4262 FinishCurrentBlock(compare); | 4364 FinishCurrentBlock(compare); |
| 4263 | 4365 |
| 4264 set_current_block(body_block); | 4366 set_current_block(body_block); |
| (...skipping 1853 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6118 ASSERT(!HasStackOverflow()); | 6220 ASSERT(!HasStackOverflow()); |
| 6119 ASSERT(current_block() != NULL); | 6221 ASSERT(current_block() != NULL); |
| 6120 ASSERT(current_block()->HasPredecessor()); | 6222 ASSERT(current_block()->HasPredecessor()); |
| 6121 // We don't optimize functions with invalid left-hand sides in | 6223 // We don't optimize functions with invalid left-hand sides in |
| 6122 // assignments, count operations, or for-in. Consequently throw can | 6224 // assignments, count operations, or for-in. Consequently throw can |
| 6123 // currently only occur in an effect context. | 6225 // currently only occur in an effect context. |
| 6124 ASSERT(ast_context()->IsEffect()); | 6226 ASSERT(ast_context()->IsEffect()); |
| 6125 CHECK_ALIVE(VisitForValue(expr->exception())); | 6227 CHECK_ALIVE(VisitForValue(expr->exception())); |
| 6126 | 6228 |
| 6127 HValue* value = environment()->Pop(); | 6229 HValue* value = environment()->Pop(); |
| 6128 if (!FLAG_emit_opt_code_positions) SetSourcePosition(expr->position()); | 6230 if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); |
| 6129 Add<HThrow>(value); | 6231 Add<HThrow>(value); |
| 6130 Add<HSimulate>(expr->id()); | 6232 Add<HSimulate>(expr->id()); |
| 6131 | 6233 |
| 6132 // If the throw definitely exits the function, we can finish with a dummy | 6234 // If the throw definitely exits the function, we can finish with a dummy |
| 6133 // control flow at this point. This is not the case if the throw is inside | 6235 // control flow at this point. This is not the case if the throw is inside |
| 6134 // an inlined function which may be replaced. | 6236 // an inlined function which may be replaced. |
| 6135 if (call_context() == NULL) { | 6237 if (call_context() == NULL) { |
| 6136 FinishExitCurrentBlock(New<HAbnormalExit>()); | 6238 FinishExitCurrentBlock(New<HAbnormalExit>()); |
| 6137 } | 6239 } |
| 6138 } | 6240 } |
| (...skipping 975 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7114 int nodes_added = target_shared->ast_node_count(); | 7216 int nodes_added = target_shared->ast_node_count(); |
| 7115 return nodes_added; | 7217 return nodes_added; |
| 7116 } | 7218 } |
| 7117 | 7219 |
| 7118 | 7220 |
| 7119 bool HOptimizedGraphBuilder::TryInline(Handle<JSFunction> target, | 7221 bool HOptimizedGraphBuilder::TryInline(Handle<JSFunction> target, |
| 7120 int arguments_count, | 7222 int arguments_count, |
| 7121 HValue* implicit_return_value, | 7223 HValue* implicit_return_value, |
| 7122 BailoutId ast_id, | 7224 BailoutId ast_id, |
| 7123 BailoutId return_id, | 7225 BailoutId return_id, |
| 7124 InliningKind inlining_kind) { | 7226 InliningKind inlining_kind, |
| 7227 HSourcePosition position) { |
| 7125 int nodes_added = InliningAstSize(target); | 7228 int nodes_added = InliningAstSize(target); |
| 7126 if (nodes_added == kNotInlinable) return false; | 7229 if (nodes_added == kNotInlinable) return false; |
| 7127 | 7230 |
| 7128 Handle<JSFunction> caller = current_info()->closure(); | 7231 Handle<JSFunction> caller = current_info()->closure(); |
| 7129 | 7232 |
| 7130 if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) { | 7233 if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) { |
| 7131 TraceInline(target, caller, "target AST is too large [early]"); | 7234 TraceInline(target, caller, "target AST is too large [early]"); |
| 7132 return false; | 7235 return false; |
| 7133 } | 7236 } |
| 7134 | 7237 |
| (...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7246 } | 7349 } |
| 7247 | 7350 |
| 7248 // ---------------------------------------------------------------- | 7351 // ---------------------------------------------------------------- |
| 7249 // After this point, we've made a decision to inline this function (so | 7352 // After this point, we've made a decision to inline this function (so |
| 7250 // TryInline should always return true). | 7353 // TryInline should always return true). |
| 7251 | 7354 |
| 7252 // Type-check the inlined function. | 7355 // Type-check the inlined function. |
| 7253 ASSERT(target_shared->has_deoptimization_support()); | 7356 ASSERT(target_shared->has_deoptimization_support()); |
| 7254 AstTyper::Run(&target_info); | 7357 AstTyper::Run(&target_info); |
| 7255 | 7358 |
| 7359 int function_id = graph()->TraceInlinedFunction(target_shared, position); |
| 7360 |
| 7256 // Save the pending call context. Set up new one for the inlined function. | 7361 // Save the pending call context. Set up new one for the inlined function. |
| 7257 // The function state is new-allocated because we need to delete it | 7362 // The function state is new-allocated because we need to delete it |
| 7258 // in two different places. | 7363 // in two different places. |
| 7259 FunctionState* target_state = new FunctionState( | 7364 FunctionState* target_state = new FunctionState( |
| 7260 this, &target_info, inlining_kind); | 7365 this, &target_info, inlining_kind, function_id); |
| 7261 | 7366 |
| 7262 HConstant* undefined = graph()->GetConstantUndefined(); | 7367 HConstant* undefined = graph()->GetConstantUndefined(); |
| 7263 | 7368 |
| 7264 HEnvironment* inner_env = | 7369 HEnvironment* inner_env = |
| 7265 environment()->CopyForInlining(target, | 7370 environment()->CopyForInlining(target, |
| 7266 arguments_count, | 7371 arguments_count, |
| 7267 function, | 7372 function, |
| 7268 undefined, | 7373 undefined, |
| 7269 function_state()->inlining_kind()); | 7374 function_state()->inlining_kind()); |
| 7270 | 7375 |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7397 return true; | 7502 return true; |
| 7398 } | 7503 } |
| 7399 | 7504 |
| 7400 | 7505 |
| 7401 bool HOptimizedGraphBuilder::TryInlineCall(Call* expr, bool drop_extra) { | 7506 bool HOptimizedGraphBuilder::TryInlineCall(Call* expr, bool drop_extra) { |
| 7402 return TryInline(expr->target(), | 7507 return TryInline(expr->target(), |
| 7403 expr->arguments()->length(), | 7508 expr->arguments()->length(), |
| 7404 NULL, | 7509 NULL, |
| 7405 expr->id(), | 7510 expr->id(), |
| 7406 expr->ReturnId(), | 7511 expr->ReturnId(), |
| 7407 drop_extra ? DROP_EXTRA_ON_RETURN : NORMAL_RETURN); | 7512 drop_extra ? DROP_EXTRA_ON_RETURN : NORMAL_RETURN, |
| 7513 ScriptPositionToSourcePosition(expr->position())); |
| 7408 } | 7514 } |
| 7409 | 7515 |
| 7410 | 7516 |
| 7411 bool HOptimizedGraphBuilder::TryInlineConstruct(CallNew* expr, | 7517 bool HOptimizedGraphBuilder::TryInlineConstruct(CallNew* expr, |
| 7412 HValue* implicit_return_value) { | 7518 HValue* implicit_return_value) { |
| 7413 return TryInline(expr->target(), | 7519 return TryInline(expr->target(), |
| 7414 expr->arguments()->length(), | 7520 expr->arguments()->length(), |
| 7415 implicit_return_value, | 7521 implicit_return_value, |
| 7416 expr->id(), | 7522 expr->id(), |
| 7417 expr->ReturnId(), | 7523 expr->ReturnId(), |
| 7418 CONSTRUCT_CALL_RETURN); | 7524 CONSTRUCT_CALL_RETURN, |
| 7525 ScriptPositionToSourcePosition(expr->position())); |
| 7419 } | 7526 } |
| 7420 | 7527 |
| 7421 | 7528 |
| 7422 bool HOptimizedGraphBuilder::TryInlineGetter(Handle<JSFunction> getter, | 7529 bool HOptimizedGraphBuilder::TryInlineGetter(Handle<JSFunction> getter, |
| 7423 BailoutId ast_id, | 7530 BailoutId ast_id, |
| 7424 BailoutId return_id) { | 7531 BailoutId return_id) { |
| 7425 return TryInline(getter, | 7532 return TryInline(getter, |
| 7426 0, | 7533 0, |
| 7427 NULL, | 7534 NULL, |
| 7428 ast_id, | 7535 ast_id, |
| 7429 return_id, | 7536 return_id, |
| 7430 GETTER_CALL_RETURN); | 7537 GETTER_CALL_RETURN, |
| 7538 source_position()); |
| 7431 } | 7539 } |
| 7432 | 7540 |
| 7433 | 7541 |
| 7434 bool HOptimizedGraphBuilder::TryInlineSetter(Handle<JSFunction> setter, | 7542 bool HOptimizedGraphBuilder::TryInlineSetter(Handle<JSFunction> setter, |
| 7435 BailoutId id, | 7543 BailoutId id, |
| 7436 BailoutId assignment_id, | 7544 BailoutId assignment_id, |
| 7437 HValue* implicit_return_value) { | 7545 HValue* implicit_return_value) { |
| 7438 return TryInline(setter, | 7546 return TryInline(setter, |
| 7439 1, | 7547 1, |
| 7440 implicit_return_value, | 7548 implicit_return_value, |
| 7441 id, assignment_id, | 7549 id, assignment_id, |
| 7442 SETTER_CALL_RETURN); | 7550 SETTER_CALL_RETURN, |
| 7551 source_position()); |
| 7443 } | 7552 } |
| 7444 | 7553 |
| 7445 | 7554 |
| 7446 bool HOptimizedGraphBuilder::TryInlineApply(Handle<JSFunction> function, | 7555 bool HOptimizedGraphBuilder::TryInlineApply(Handle<JSFunction> function, |
| 7447 Call* expr, | 7556 Call* expr, |
| 7448 int arguments_count) { | 7557 int arguments_count) { |
| 7449 return TryInline(function, | 7558 return TryInline(function, |
| 7450 arguments_count, | 7559 arguments_count, |
| 7451 NULL, | 7560 NULL, |
| 7452 expr->id(), | 7561 expr->id(), |
| 7453 expr->ReturnId(), | 7562 expr->ReturnId(), |
| 7454 NORMAL_RETURN); | 7563 NORMAL_RETURN, |
| 7564 ScriptPositionToSourcePosition(expr->position())); |
| 7455 } | 7565 } |
| 7456 | 7566 |
| 7457 | 7567 |
| 7458 bool HOptimizedGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr, | 7568 bool HOptimizedGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr, |
| 7459 bool drop_extra) { | 7569 bool drop_extra) { |
| 7460 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; | 7570 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; |
| 7461 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); | 7571 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); |
| 7462 switch (id) { | 7572 switch (id) { |
| 7463 case kMathExp: | 7573 case kMathExp: |
| 7464 if (!FLAG_fast_math) break; | 7574 if (!FLAG_fast_math) break; |
| (...skipping 381 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7846 Drop(argument_count + 1); // 1 is the key. | 7956 Drop(argument_count + 1); // 1 is the key. |
| 7847 return ast_context()->ReturnInstruction(call, expr->id()); | 7957 return ast_context()->ReturnInstruction(call, expr->id()); |
| 7848 } | 7958 } |
| 7849 | 7959 |
| 7850 // Named function call. | 7960 // Named function call. |
| 7851 if (TryCallApply(expr)) return; | 7961 if (TryCallApply(expr)) return; |
| 7852 | 7962 |
| 7853 CHECK_ALIVE(VisitForValue(prop->obj())); | 7963 CHECK_ALIVE(VisitForValue(prop->obj())); |
| 7854 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 7964 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
| 7855 | 7965 |
| 7966 if (FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); |
| 7967 |
| 7856 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); | 7968 Handle<String> name = prop->key()->AsLiteral()->AsPropertyName(); |
| 7857 HValue* receiver = | 7969 HValue* receiver = |
| 7858 environment()->ExpressionStackAt(expr->arguments()->length()); | 7970 environment()->ExpressionStackAt(expr->arguments()->length()); |
| 7859 | 7971 |
| 7860 SmallMapList* types; | 7972 SmallMapList* types; |
| 7861 bool was_monomorphic = expr->IsMonomorphic(); | 7973 bool was_monomorphic = expr->IsMonomorphic(); |
| 7862 bool monomorphic = ComputeReceiverTypes(expr, receiver, &types); | 7974 bool monomorphic = ComputeReceiverTypes(expr, receiver, &types); |
| 7863 if (!was_monomorphic && monomorphic) { | 7975 if (!was_monomorphic && monomorphic) { |
| 7864 monomorphic = expr->ComputeTarget(types->first(), name); | 7976 monomorphic = expr->ComputeTarget(types->first(), name); |
| 7865 } | 7977 } |
| (...skipping 269 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8135 TraceInline(target, caller, NULL); | 8247 TraceInline(target, caller, NULL); |
| 8136 } | 8248 } |
| 8137 return inline_ok; | 8249 return inline_ok; |
| 8138 } | 8250 } |
| 8139 | 8251 |
| 8140 | 8252 |
| 8141 void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) { | 8253 void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) { |
| 8142 ASSERT(!HasStackOverflow()); | 8254 ASSERT(!HasStackOverflow()); |
| 8143 ASSERT(current_block() != NULL); | 8255 ASSERT(current_block() != NULL); |
| 8144 ASSERT(current_block()->HasPredecessor()); | 8256 ASSERT(current_block()->HasPredecessor()); |
| 8145 if (!FLAG_emit_opt_code_positions) SetSourcePosition(expr->position()); | 8257 if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); |
| 8146 int argument_count = expr->arguments()->length() + 1; // Plus constructor. | 8258 int argument_count = expr->arguments()->length() + 1; // Plus constructor. |
| 8147 Factory* factory = isolate()->factory(); | 8259 Factory* factory = isolate()->factory(); |
| 8148 | 8260 |
| 8149 // The constructor function is on the stack in the unoptimized code | 8261 // The constructor function is on the stack in the unoptimized code |
| 8150 // during evaluation of the arguments. | 8262 // during evaluation of the arguments. |
| 8151 CHECK_ALIVE(VisitForValue(expr->expression())); | 8263 CHECK_ALIVE(VisitForValue(expr->expression())); |
| 8152 HValue* function = Top(); | 8264 HValue* function = Top(); |
| 8153 CHECK_ALIVE(VisitExpressions(expr->arguments())); | 8265 CHECK_ALIVE(VisitExpressions(expr->arguments())); |
| 8154 | 8266 |
| 8155 if (FLAG_inline_construct && | 8267 if (FLAG_inline_construct && |
| (...skipping 517 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8673 if (key != NULL) Push(key); | 8785 if (key != NULL) Push(key); |
| 8674 Push(value); | 8786 Push(value); |
| 8675 BuildStore(expr, prop, ast_id, return_id); | 8787 BuildStore(expr, prop, ast_id, return_id); |
| 8676 } | 8788 } |
| 8677 | 8789 |
| 8678 | 8790 |
| 8679 void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) { | 8791 void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) { |
| 8680 ASSERT(!HasStackOverflow()); | 8792 ASSERT(!HasStackOverflow()); |
| 8681 ASSERT(current_block() != NULL); | 8793 ASSERT(current_block() != NULL); |
| 8682 ASSERT(current_block()->HasPredecessor()); | 8794 ASSERT(current_block()->HasPredecessor()); |
| 8683 if (!FLAG_emit_opt_code_positions) SetSourcePosition(expr->position()); | 8795 if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); |
| 8684 Expression* target = expr->expression(); | 8796 Expression* target = expr->expression(); |
| 8685 VariableProxy* proxy = target->AsVariableProxy(); | 8797 VariableProxy* proxy = target->AsVariableProxy(); |
| 8686 Property* prop = target->AsProperty(); | 8798 Property* prop = target->AsProperty(); |
| 8687 if (proxy == NULL && prop == NULL) { | 8799 if (proxy == NULL && prop == NULL) { |
| 8688 return Bailout(kInvalidLhsInCountOperation); | 8800 return Bailout(kInvalidLhsInCountOperation); |
| 8689 } | 8801 } |
| 8690 | 8802 |
| 8691 // Match the full code generator stack by simulating an extra stack | 8803 // Match the full code generator stack by simulating an extra stack |
| 8692 // element for postfix operations in a non-effect context. The return | 8804 // element for postfix operations in a non-effect context. The return |
| 8693 // value is ToNumber(input). | 8805 // value is ToNumber(input). |
| (...skipping 631 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9325 } | 9437 } |
| 9326 | 9438 |
| 9327 | 9439 |
| 9328 void HOptimizedGraphBuilder::VisitArithmeticExpression(BinaryOperation* expr) { | 9440 void HOptimizedGraphBuilder::VisitArithmeticExpression(BinaryOperation* expr) { |
| 9329 CHECK_ALIVE(VisitForValue(expr->left())); | 9441 CHECK_ALIVE(VisitForValue(expr->left())); |
| 9330 CHECK_ALIVE(VisitForValue(expr->right())); | 9442 CHECK_ALIVE(VisitForValue(expr->right())); |
| 9331 SetSourcePosition(expr->position()); | 9443 SetSourcePosition(expr->position()); |
| 9332 HValue* right = Pop(); | 9444 HValue* right = Pop(); |
| 9333 HValue* left = Pop(); | 9445 HValue* left = Pop(); |
| 9334 HValue* result = BuildBinaryOperation(expr, left, right); | 9446 HValue* result = BuildBinaryOperation(expr, left, right); |
| 9335 if (FLAG_emit_opt_code_positions && result->IsBinaryOperation()) { | 9447 if (FLAG_hydrogen_track_positions && result->IsBinaryOperation()) { |
| 9336 HBinaryOperation::cast(result)->SetOperandPositions( | 9448 HBinaryOperation::cast(result)->SetOperandPositions( |
| 9337 zone(), expr->left()->position(), expr->right()->position()); | 9449 zone(), |
| 9450 ScriptPositionToSourcePosition(expr->left()->position()), |
| 9451 ScriptPositionToSourcePosition(expr->right()->position())); |
| 9338 } | 9452 } |
| 9339 return ast_context()->ReturnValue(result); | 9453 return ast_context()->ReturnValue(result); |
| 9340 } | 9454 } |
| 9341 | 9455 |
| 9342 | 9456 |
| 9343 void HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr, | 9457 void HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr, |
| 9344 Expression* sub_expr, | 9458 Expression* sub_expr, |
| 9345 Handle<String> check) { | 9459 Handle<String> check) { |
| 9346 CHECK_ALIVE(VisitForTypeOf(sub_expr)); | 9460 CHECK_ALIVE(VisitForTypeOf(sub_expr)); |
| 9347 SetSourcePosition(expr->position()); | 9461 SetSourcePosition(expr->position()); |
| (...skipping 13 matching lines...) Expand all Loading... |
| 9361 (right->IsConstant() && | 9475 (right->IsConstant() && |
| 9362 HConstant::cast(right)->handle(isolate)->IsBoolean())); | 9476 HConstant::cast(right)->handle(isolate)->IsBoolean())); |
| 9363 } | 9477 } |
| 9364 | 9478 |
| 9365 | 9479 |
| 9366 void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) { | 9480 void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) { |
| 9367 ASSERT(!HasStackOverflow()); | 9481 ASSERT(!HasStackOverflow()); |
| 9368 ASSERT(current_block() != NULL); | 9482 ASSERT(current_block() != NULL); |
| 9369 ASSERT(current_block()->HasPredecessor()); | 9483 ASSERT(current_block()->HasPredecessor()); |
| 9370 | 9484 |
| 9371 if (!FLAG_emit_opt_code_positions) SetSourcePosition(expr->position()); | 9485 if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); |
| 9372 | 9486 |
| 9373 // Check for a few fast cases. The AST visiting behavior must be in sync | 9487 // Check for a few fast cases. The AST visiting behavior must be in sync |
| 9374 // with the full codegen: We don't push both left and right values onto | 9488 // with the full codegen: We don't push both left and right values onto |
| 9375 // the expression stack when one side is a special-case literal. | 9489 // the expression stack when one side is a special-case literal. |
| 9376 Expression* sub_expr = NULL; | 9490 Expression* sub_expr = NULL; |
| 9377 Handle<String> check; | 9491 Handle<String> check; |
| 9378 if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) { | 9492 if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) { |
| 9379 return HandleLiteralCompareTypeof(expr, sub_expr, check); | 9493 return HandleLiteralCompareTypeof(expr, sub_expr, check); |
| 9380 } | 9494 } |
| 9381 if (expr->IsLiteralCompareUndefined(&sub_expr, isolate())) { | 9495 if (expr->IsLiteralCompareUndefined(&sub_expr, isolate())) { |
| (...skipping 14 matching lines...) Expand all Loading... |
| 9396 return ast_context()->ReturnControl(instr, expr->id()); | 9510 return ast_context()->ReturnControl(instr, expr->id()); |
| 9397 } | 9511 } |
| 9398 | 9512 |
| 9399 Type* left_type = expr->left()->bounds().lower; | 9513 Type* left_type = expr->left()->bounds().lower; |
| 9400 Type* right_type = expr->right()->bounds().lower; | 9514 Type* right_type = expr->right()->bounds().lower; |
| 9401 Type* combined_type = expr->combined_type(); | 9515 Type* combined_type = expr->combined_type(); |
| 9402 | 9516 |
| 9403 CHECK_ALIVE(VisitForValue(expr->left())); | 9517 CHECK_ALIVE(VisitForValue(expr->left())); |
| 9404 CHECK_ALIVE(VisitForValue(expr->right())); | 9518 CHECK_ALIVE(VisitForValue(expr->right())); |
| 9405 | 9519 |
| 9406 if (FLAG_emit_opt_code_positions) SetSourcePosition(expr->position()); | 9520 if (FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); |
| 9407 | 9521 |
| 9408 HValue* right = Pop(); | 9522 HValue* right = Pop(); |
| 9409 HValue* left = Pop(); | 9523 HValue* left = Pop(); |
| 9410 Token::Value op = expr->op(); | 9524 Token::Value op = expr->op(); |
| 9411 | 9525 |
| 9412 if (IsLiteralCompareBool(isolate(), left, op, right)) { | 9526 if (IsLiteralCompareBool(isolate(), left, op, right)) { |
| 9413 HCompareObjectEqAndBranch* result = | 9527 HCompareObjectEqAndBranch* result = |
| 9414 New<HCompareObjectEqAndBranch>(left, right); | 9528 New<HCompareObjectEqAndBranch>(left, right); |
| 9415 return ast_context()->ReturnControl(result, expr->id()); | 9529 return ast_context()->ReturnControl(result, expr->id()); |
| 9416 } | 9530 } |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 9458 Add<HPushArgument>(left); | 9572 Add<HPushArgument>(left); |
| 9459 Add<HPushArgument>(right); | 9573 Add<HPushArgument>(right); |
| 9460 // TODO(olivf) InvokeFunction produces a check for the parameter count, | 9574 // TODO(olivf) InvokeFunction produces a check for the parameter count, |
| 9461 // even though we are certain to pass the correct number of arguments here. | 9575 // even though we are certain to pass the correct number of arguments here. |
| 9462 HInstruction* result = New<HInvokeFunction>(function, 2); | 9576 HInstruction* result = New<HInvokeFunction>(function, 2); |
| 9463 return ast_context()->ReturnInstruction(result, expr->id()); | 9577 return ast_context()->ReturnInstruction(result, expr->id()); |
| 9464 } | 9578 } |
| 9465 | 9579 |
| 9466 HControlInstruction* compare = BuildCompareInstruction( | 9580 HControlInstruction* compare = BuildCompareInstruction( |
| 9467 op, left, right, left_type, right_type, combined_type, | 9581 op, left, right, left_type, right_type, combined_type, |
| 9468 expr->left()->position(), expr->right()->position(), expr->id()); | 9582 ScriptPositionToSourcePosition(expr->left()->position()), |
| 9583 ScriptPositionToSourcePosition(expr->right()->position()), |
| 9584 expr->id()); |
| 9469 if (compare == NULL) return; // Bailed out. | 9585 if (compare == NULL) return; // Bailed out. |
| 9470 return ast_context()->ReturnControl(compare, expr->id()); | 9586 return ast_context()->ReturnControl(compare, expr->id()); |
| 9471 } | 9587 } |
| 9472 | 9588 |
| 9473 | 9589 |
| 9474 HControlInstruction* HOptimizedGraphBuilder::BuildCompareInstruction( | 9590 HControlInstruction* HOptimizedGraphBuilder::BuildCompareInstruction( |
| 9475 Token::Value op, | 9591 Token::Value op, |
| 9476 HValue* left, | 9592 HValue* left, |
| 9477 HValue* right, | 9593 HValue* right, |
| 9478 Type* left_type, | 9594 Type* left_type, |
| 9479 Type* right_type, | 9595 Type* right_type, |
| 9480 Type* combined_type, | 9596 Type* combined_type, |
| 9481 int left_position, | 9597 HSourcePosition left_position, |
| 9482 int right_position, | 9598 HSourcePosition right_position, |
| 9483 BailoutId bailout_id) { | 9599 BailoutId bailout_id) { |
| 9484 // Cases handled below depend on collected type feedback. They should | 9600 // Cases handled below depend on collected type feedback. They should |
| 9485 // soft deoptimize when there is no type feedback. | 9601 // soft deoptimize when there is no type feedback. |
| 9486 if (combined_type->Is(Type::None())) { | 9602 if (combined_type->Is(Type::None())) { |
| 9487 Add<HDeoptimize>("Insufficient type feedback for combined type " | 9603 Add<HDeoptimize>("Insufficient type feedback for combined type " |
| 9488 "of binary operation", | 9604 "of binary operation", |
| 9489 Deoptimizer::SOFT); | 9605 Deoptimizer::SOFT); |
| 9490 combined_type = left_type = right_type = Type::Any(zone()); | 9606 combined_type = left_type = right_type = Type::Any(zone()); |
| 9491 } | 9607 } |
| 9492 | 9608 |
| 9493 Representation left_rep = Representation::FromType(left_type); | 9609 Representation left_rep = Representation::FromType(left_type); |
| 9494 Representation right_rep = Representation::FromType(right_type); | 9610 Representation right_rep = Representation::FromType(right_type); |
| 9495 Representation combined_rep = Representation::FromType(combined_type); | 9611 Representation combined_rep = Representation::FromType(combined_type); |
| 9496 | 9612 |
| 9497 if (combined_type->Is(Type::Receiver())) { | 9613 if (combined_type->Is(Type::Receiver())) { |
| 9498 if (Token::IsEqualityOp(op)) { | 9614 if (Token::IsEqualityOp(op)) { |
| 9499 // Can we get away with map check and not instance type check? | 9615 // Can we get away with map check and not instance type check? |
| 9500 HValue* operand_to_check = | 9616 HValue* operand_to_check = |
| 9501 left->block()->block_id() < right->block()->block_id() ? left : right; | 9617 left->block()->block_id() < right->block()->block_id() ? left : right; |
| 9502 if (combined_type->IsClass()) { | 9618 if (combined_type->IsClass()) { |
| 9503 Handle<Map> map = combined_type->AsClass(); | 9619 Handle<Map> map = combined_type->AsClass(); |
| 9504 AddCheckMap(operand_to_check, map); | 9620 AddCheckMap(operand_to_check, map); |
| 9505 HCompareObjectEqAndBranch* result = | 9621 HCompareObjectEqAndBranch* result = |
| 9506 New<HCompareObjectEqAndBranch>(left, right); | 9622 New<HCompareObjectEqAndBranch>(left, right); |
| 9507 if (FLAG_emit_opt_code_positions) { | 9623 if (FLAG_hydrogen_track_positions) { |
| 9508 result->set_operand_position(zone(), 0, left_position); | 9624 result->set_operand_position(zone(), 0, left_position); |
| 9509 result->set_operand_position(zone(), 1, right_position); | 9625 result->set_operand_position(zone(), 1, right_position); |
| 9510 } | 9626 } |
| 9511 return result; | 9627 return result; |
| 9512 } else { | 9628 } else { |
| 9513 BuildCheckHeapObject(operand_to_check); | 9629 BuildCheckHeapObject(operand_to_check); |
| 9514 Add<HCheckInstanceType>(operand_to_check, | 9630 Add<HCheckInstanceType>(operand_to_check, |
| 9515 HCheckInstanceType::IS_SPEC_OBJECT); | 9631 HCheckInstanceType::IS_SPEC_OBJECT); |
| 9516 HCompareObjectEqAndBranch* result = | 9632 HCompareObjectEqAndBranch* result = |
| 9517 New<HCompareObjectEqAndBranch>(left, right); | 9633 New<HCompareObjectEqAndBranch>(left, right); |
| (...skipping 30 matching lines...) Expand all Loading... |
| 9548 AddSimulate(bailout_id, REMOVABLE_SIMULATE); | 9664 AddSimulate(bailout_id, REMOVABLE_SIMULATE); |
| 9549 Drop(1); | 9665 Drop(1); |
| 9550 } | 9666 } |
| 9551 // TODO(jkummerow): Can we make this more efficient? | 9667 // TODO(jkummerow): Can we make this more efficient? |
| 9552 HBranch* branch = New<HBranch>(result); | 9668 HBranch* branch = New<HBranch>(result); |
| 9553 return branch; | 9669 return branch; |
| 9554 } else { | 9670 } else { |
| 9555 HCompareNumericAndBranch* result = | 9671 HCompareNumericAndBranch* result = |
| 9556 New<HCompareNumericAndBranch>(left, right, op); | 9672 New<HCompareNumericAndBranch>(left, right, op); |
| 9557 result->set_observed_input_representation(left_rep, right_rep); | 9673 result->set_observed_input_representation(left_rep, right_rep); |
| 9558 if (FLAG_emit_opt_code_positions) { | 9674 if (FLAG_hydrogen_track_positions) { |
| 9559 result->SetOperandPositions(zone(), left_position, right_position); | 9675 result->SetOperandPositions(zone(), left_position, right_position); |
| 9560 } | 9676 } |
| 9561 return result; | 9677 return result; |
| 9562 } | 9678 } |
| 9563 } | 9679 } |
| 9564 } | 9680 } |
| 9565 | 9681 |
| 9566 | 9682 |
| 9567 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, | 9683 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, |
| 9568 Expression* sub_expr, | 9684 Expression* sub_expr, |
| 9569 NilValue nil) { | 9685 NilValue nil) { |
| 9570 ASSERT(!HasStackOverflow()); | 9686 ASSERT(!HasStackOverflow()); |
| 9571 ASSERT(current_block() != NULL); | 9687 ASSERT(current_block() != NULL); |
| 9572 ASSERT(current_block()->HasPredecessor()); | 9688 ASSERT(current_block()->HasPredecessor()); |
| 9573 ASSERT(expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT); | 9689 ASSERT(expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT); |
| 9574 if (!FLAG_emit_opt_code_positions) SetSourcePosition(expr->position()); | 9690 if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position()); |
| 9575 CHECK_ALIVE(VisitForValue(sub_expr)); | 9691 CHECK_ALIVE(VisitForValue(sub_expr)); |
| 9576 HValue* value = Pop(); | 9692 HValue* value = Pop(); |
| 9577 if (expr->op() == Token::EQ_STRICT) { | 9693 if (expr->op() == Token::EQ_STRICT) { |
| 9578 HConstant* nil_constant = nil == kNullValue | 9694 HConstant* nil_constant = nil == kNullValue |
| 9579 ? graph()->GetConstantNull() | 9695 ? graph()->GetConstantNull() |
| 9580 : graph()->GetConstantUndefined(); | 9696 : graph()->GetConstantUndefined(); |
| 9581 HCompareObjectEqAndBranch* instr = | 9697 HCompareObjectEqAndBranch* instr = |
| 9582 New<HCompareObjectEqAndBranch>(value, nil_constant); | 9698 New<HCompareObjectEqAndBranch>(value, nil_constant); |
| 9583 return ast_context()->ReturnControl(instr, expr->id()); | 9699 return ast_context()->ReturnControl(instr, expr->id()); |
| 9584 } else { | 9700 } else { |
| (...skipping 1176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10761 PrintTo(&trace); | 10877 PrintTo(&trace); |
| 10762 PrintF("%s", trace.ToCString().get()); | 10878 PrintF("%s", trace.ToCString().get()); |
| 10763 } | 10879 } |
| 10764 | 10880 |
| 10765 | 10881 |
| 10766 void HTracer::TraceCompilation(CompilationInfo* info) { | 10882 void HTracer::TraceCompilation(CompilationInfo* info) { |
| 10767 Tag tag(this, "compilation"); | 10883 Tag tag(this, "compilation"); |
| 10768 if (info->IsOptimizing()) { | 10884 if (info->IsOptimizing()) { |
| 10769 Handle<String> name = info->function()->debug_name(); | 10885 Handle<String> name = info->function()->debug_name(); |
| 10770 PrintStringProperty("name", name->ToCString().get()); | 10886 PrintStringProperty("name", name->ToCString().get()); |
| 10771 PrintStringProperty("method", name->ToCString().get()); | 10887 PrintIndent(); |
| 10888 trace_.Add("method \"%s:%d\"\n", |
| 10889 name->ToCString().get(), |
| 10890 info->optimization_id()); |
| 10772 } else { | 10891 } else { |
| 10773 CodeStub::Major major_key = info->code_stub()->MajorKey(); | 10892 CodeStub::Major major_key = info->code_stub()->MajorKey(); |
| 10774 PrintStringProperty("name", CodeStub::MajorName(major_key, false)); | 10893 PrintStringProperty("name", CodeStub::MajorName(major_key, false)); |
| 10775 PrintStringProperty("method", "stub"); | 10894 PrintStringProperty("method", "stub"); |
| 10776 } | 10895 } |
| 10777 PrintLongProperty("date", static_cast<int64_t>(OS::TimeCurrentMillis())); | 10896 PrintLongProperty("date", static_cast<int64_t>(OS::TimeCurrentMillis())); |
| 10778 } | 10897 } |
| 10779 | 10898 |
| 10780 | 10899 |
| 10781 void HTracer::TraceLithium(const char* name, LChunk* chunk) { | 10900 void HTracer::TraceLithium(const char* name, LChunk* chunk) { |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 10875 trace_.Add(" "); | 10994 trace_.Add(" "); |
| 10876 phi->PrintTo(&trace_); | 10995 phi->PrintTo(&trace_); |
| 10877 trace_.Add("\n"); | 10996 trace_.Add("\n"); |
| 10878 } | 10997 } |
| 10879 } | 10998 } |
| 10880 | 10999 |
| 10881 { | 11000 { |
| 10882 Tag HIR_tag(this, "HIR"); | 11001 Tag HIR_tag(this, "HIR"); |
| 10883 for (HInstructionIterator it(current); !it.Done(); it.Advance()) { | 11002 for (HInstructionIterator it(current); !it.Done(); it.Advance()) { |
| 10884 HInstruction* instruction = it.Current(); | 11003 HInstruction* instruction = it.Current(); |
| 10885 int bci = FLAG_emit_opt_code_positions && instruction->has_position() ? | |
| 10886 instruction->position() : 0; | |
| 10887 int uses = instruction->UseCount(); | 11004 int uses = instruction->UseCount(); |
| 10888 PrintIndent(); | 11005 PrintIndent(); |
| 10889 trace_.Add("%d %d ", bci, uses); | 11006 trace_.Add("0 %d ", uses); |
| 10890 instruction->PrintNameTo(&trace_); | 11007 instruction->PrintNameTo(&trace_); |
| 10891 trace_.Add(" "); | 11008 trace_.Add(" "); |
| 10892 instruction->PrintTo(&trace_); | 11009 instruction->PrintTo(&trace_); |
| 11010 if (FLAG_hydrogen_track_positions && |
| 11011 instruction->has_position() && |
| 11012 instruction->position().raw() != 0) { |
| 11013 const HSourcePosition pos = instruction->position(); |
| 11014 trace_.Add(" pos:"); |
| 11015 if (pos.inlining_id() != 0) { |
| 11016 trace_.Add("%d_", pos.inlining_id()); |
| 11017 } |
| 11018 trace_.Add("%d", pos.position()); |
| 11019 } |
| 10893 trace_.Add(" <|@\n"); | 11020 trace_.Add(" <|@\n"); |
| 10894 } | 11021 } |
| 10895 } | 11022 } |
| 10896 | 11023 |
| 10897 | 11024 |
| 10898 if (chunk != NULL) { | 11025 if (chunk != NULL) { |
| 10899 Tag LIR_tag(this, "LIR"); | 11026 Tag LIR_tag(this, "LIR"); |
| 10900 int first_index = current->first_instruction_index(); | 11027 int first_index = current->first_instruction_index(); |
| 10901 int last_index = current->last_instruction_index(); | 11028 int last_index = current->last_instruction_index(); |
| 10902 if (first_index != -1 && last_index != -1) { | 11029 if (first_index != -1 && last_index != -1) { |
| (...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 11083 if (ShouldProduceTraceOutput()) { | 11210 if (ShouldProduceTraceOutput()) { |
| 11084 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); | 11211 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); |
| 11085 } | 11212 } |
| 11086 | 11213 |
| 11087 #ifdef DEBUG | 11214 #ifdef DEBUG |
| 11088 graph_->Verify(false); // No full verify. | 11215 graph_->Verify(false); // No full verify. |
| 11089 #endif | 11216 #endif |
| 11090 } | 11217 } |
| 11091 | 11218 |
| 11092 } } // namespace v8::internal | 11219 } } // namespace v8::internal |
| OLD | NEW |