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

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

Powered by Google App Engine
This is Rietveld 408576698