Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1416)

Side by Side Diff: src/hydrogen.cc

Issue 140683011: Improve positions tracking inside the HGraphBuilder. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
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
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698