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

Side by Side Diff: src/hydrogen.cc

Issue 211393007: Backport https://code.google.com/p/v8/source/detail?r=19360 to 3.24.35 (Closed) Base URL: https://github.com/v8/v8.git@3.24
Patch Set: Created 6 years, 9 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
« 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 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() == NORMAL_RETURN; 229 state->inlining_kind() == NORMAL_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() == NORMAL_RETURN; 250 bool drop_extra = state->inlining_kind() == NORMAL_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 767 matching lines...) Expand 10 before | Expand all | Expand 10 after
1025 } 1026 }
1026 builder_->GotoNoSimulate(current->block_, merge_block); 1027 builder_->GotoNoSimulate(current->block_, merge_block);
1027 } 1028 }
1028 current = current->next_; 1029 current = current->next_;
1029 } 1030 }
1030 1031
1031 // Merge deopt blocks, padding when necessary. 1032 // Merge deopt blocks, padding when necessary.
1032 current = merge_at_join_blocks_; 1033 current = merge_at_join_blocks_;
1033 while (current != NULL) { 1034 while (current != NULL) {
1034 if (current->deopt_ && current->block_ != NULL) { 1035 if (current->deopt_ && current->block_ != NULL) {
1035 builder_->PadEnvironmentForContinuation(current->block_, 1036 current->block_->FinishExit(
1036 merge_block); 1037 HAbnormalExit::New(builder_->zone(), NULL),
1037 builder_->GotoNoSimulate(current->block_, merge_block); 1038 HSourcePosition::Unknown());
1038 } 1039 }
1039 current = current->next_; 1040 current = current->next_;
1040 } 1041 }
1041 builder_->set_current_block(merge_block); 1042 builder_->set_current_block(merge_block);
1042 } 1043 }
1043 1044
1044 1045
1045 HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder, 1046 HGraphBuilder::LoopBuilder::LoopBuilder(HGraphBuilder* builder,
1046 HValue* context, 1047 HValue* context,
1047 LoopBuilder::Direction direction) 1048 LoopBuilder::Direction direction)
(...skipping 112 matching lines...) Expand 10 before | Expand all | Expand 10 after
1160 CompilationPhase phase("H_Block building", info_); 1161 CompilationPhase phase("H_Block building", info_);
1161 set_current_block(graph()->entry_block()); 1162 set_current_block(graph()->entry_block());
1162 if (!BuildGraph()) return NULL; 1163 if (!BuildGraph()) return NULL;
1163 graph()->FinalizeUniqueness(); 1164 graph()->FinalizeUniqueness();
1164 return graph_; 1165 return graph_;
1165 } 1166 }
1166 1167
1167 1168
1168 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) { 1169 HInstruction* HGraphBuilder::AddInstruction(HInstruction* instr) {
1169 ASSERT(current_block() != NULL); 1170 ASSERT(current_block() != NULL);
1170 ASSERT(!FLAG_emit_opt_code_positions || 1171 ASSERT(!FLAG_hydrogen_track_positions ||
1171 position_ != RelocInfo::kNoPosition || !info_->IsOptimizing()); 1172 !position_.IsUnknown() ||
1172 current_block()->AddInstruction(instr, position_); 1173 !info_->IsOptimizing());
1174 current_block()->AddInstruction(instr, source_position());
1173 if (graph()->IsInsideNoSideEffectsScope()) { 1175 if (graph()->IsInsideNoSideEffectsScope()) {
1174 instr->SetFlag(HValue::kHasNoObservableSideEffects); 1176 instr->SetFlag(HValue::kHasNoObservableSideEffects);
1175 } 1177 }
1176 return instr; 1178 return instr;
1177 } 1179 }
1178 1180
1179 1181
1180 void HGraphBuilder::FinishCurrentBlock(HControlInstruction* last) { 1182 void HGraphBuilder::FinishCurrentBlock(HControlInstruction* last) {
1181 ASSERT(!FLAG_emit_opt_code_positions || !info_->IsOptimizing() || 1183 ASSERT(!FLAG_hydrogen_track_positions ||
1182 position_ != RelocInfo::kNoPosition); 1184 !info_->IsOptimizing() ||
1183 current_block()->Finish(last, position_); 1185 !position_.IsUnknown());
1186 current_block()->Finish(last, source_position());
1184 if (last->IsReturn() || last->IsAbnormalExit()) { 1187 if (last->IsReturn() || last->IsAbnormalExit()) {
1185 set_current_block(NULL); 1188 set_current_block(NULL);
1186 } 1189 }
1187 } 1190 }
1188 1191
1189 1192
1190 void HGraphBuilder::FinishExitCurrentBlock(HControlInstruction* instruction) { 1193 void HGraphBuilder::FinishExitCurrentBlock(HControlInstruction* instruction) {
1191 ASSERT(!FLAG_emit_opt_code_positions || !info_->IsOptimizing() || 1194 ASSERT(!FLAG_hydrogen_track_positions || !info_->IsOptimizing() ||
1192 position_ != RelocInfo::kNoPosition); 1195 !position_.IsUnknown());
1193 current_block()->FinishExit(instruction, position_); 1196 current_block()->FinishExit(instruction, source_position());
1194 if (instruction->IsReturn() || instruction->IsAbnormalExit()) { 1197 if (instruction->IsReturn() || instruction->IsAbnormalExit()) {
1195 set_current_block(NULL); 1198 set_current_block(NULL);
1196 } 1199 }
1197 } 1200 }
1198 1201
1199 1202
1200 void HGraphBuilder::AddIncrementCounter(StatsCounter* counter) { 1203 void HGraphBuilder::AddIncrementCounter(StatsCounter* counter) {
1201 if (FLAG_native_code_counters && counter->Enabled()) { 1204 if (FLAG_native_code_counters && counter->Enabled()) {
1202 HValue* reference = Add<HConstant>(ExternalReference(counter)); 1205 HValue* reference = Add<HConstant>(ExternalReference(counter));
1203 HValue* old_value = Add<HLoadNamedField>( 1206 HValue* old_value = Add<HLoadNamedField>(
1204 reference, static_cast<HValue*>(NULL), HObjectAccess::ForCounter()); 1207 reference, static_cast<HValue*>(NULL), HObjectAccess::ForCounter());
1205 HValue* new_value = AddUncasted<HAdd>(old_value, graph()->GetConstant1()); 1208 HValue* new_value = AddUncasted<HAdd>(old_value, graph()->GetConstant1());
1206 new_value->ClearFlag(HValue::kCanOverflow); // Ignore counter overflow 1209 new_value->ClearFlag(HValue::kCanOverflow); // Ignore counter overflow
1207 Add<HStoreNamedField>(reference, HObjectAccess::ForCounter(), 1210 Add<HStoreNamedField>(reference, HObjectAccess::ForCounter(),
1208 new_value, STORE_TO_INITIALIZED_ENTRY); 1211 new_value, STORE_TO_INITIALIZED_ENTRY);
1209 } 1212 }
1210 } 1213 }
1211 1214
1212 1215
1213 void HGraphBuilder::AddSimulate(BailoutId id, 1216 void HGraphBuilder::AddSimulate(BailoutId id,
1214 RemovableSimulate removable) { 1217 RemovableSimulate removable) {
1215 ASSERT(current_block() != NULL); 1218 ASSERT(current_block() != NULL);
1216 ASSERT(!graph()->IsInsideNoSideEffectsScope()); 1219 ASSERT(!graph()->IsInsideNoSideEffectsScope());
1217 current_block()->AddNewSimulate(id, position_, removable); 1220 current_block()->AddNewSimulate(id, source_position(), removable);
1218 } 1221 }
1219 1222
1220 1223
1221 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) { 1224 HBasicBlock* HGraphBuilder::CreateBasicBlock(HEnvironment* env) {
1222 HBasicBlock* b = graph()->CreateBasicBlock(); 1225 HBasicBlock* b = graph()->CreateBasicBlock();
1223 b->SetInitialEnvironment(env); 1226 b->SetInitialEnvironment(env);
1224 return b; 1227 return b;
1225 } 1228 }
1226 1229
1227 1230
(...skipping 1758 matching lines...) Expand 10 before | Expand all | Expand 10 after
2986 HObjectAccess function_access = HObjectAccess::ForObservableJSObjectOffset( 2989 HObjectAccess function_access = HObjectAccess::ForObservableJSObjectOffset(
2987 JSBuiltinsObject::OffsetOfFunctionWithId(builtin)); 2990 JSBuiltinsObject::OffsetOfFunctionWithId(builtin));
2988 return Add<HLoadNamedField>( 2991 return Add<HLoadNamedField>(
2989 builtins, static_cast<HValue*>(NULL), function_access); 2992 builtins, static_cast<HValue*>(NULL), function_access);
2990 } 2993 }
2991 2994
2992 2995
2993 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info) 2996 HOptimizedGraphBuilder::HOptimizedGraphBuilder(CompilationInfo* info)
2994 : HGraphBuilder(info), 2997 : HGraphBuilder(info),
2995 function_state_(NULL), 2998 function_state_(NULL),
2996 initial_function_state_(this, info, NORMAL_RETURN), 2999 initial_function_state_(this, info, NORMAL_RETURN, 0),
2997 ast_context_(NULL), 3000 ast_context_(NULL),
2998 break_scope_(NULL), 3001 break_scope_(NULL),
2999 inlined_count_(0), 3002 inlined_count_(0),
3000 globals_(10, info->zone()), 3003 globals_(10, info->zone()),
3001 inline_bailout_(false), 3004 inline_bailout_(false),
3002 osr_(new(info->zone()) HOsrBuilder(this)) { 3005 osr_(new(info->zone()) HOsrBuilder(this)) {
3003 // This is not initialized in the initializer list because the 3006 // This is not initialized in the initializer list because the
3004 // constructor for the initial state relies on function_state_ == NULL 3007 // constructor for the initial state relies on function_state_ == NULL
3005 // to know it's the initial state. 3008 // to know it's the initial state.
3006 function_state_= &initial_function_state_; 3009 function_state_= &initial_function_state_;
3007 InitializeAstVisitor(info->zone()); 3010 InitializeAstVisitor(info->zone());
3008 if (FLAG_emit_opt_code_positions) { 3011 if (FLAG_hydrogen_track_positions) {
3009 SetSourcePosition(info->shared_info()->start_position()); 3012 SetSourcePosition(info->shared_info()->start_position());
3010 } 3013 }
3011 } 3014 }
3012 3015
3013 3016
3014 HBasicBlock* HOptimizedGraphBuilder::CreateJoin(HBasicBlock* first, 3017 HBasicBlock* HOptimizedGraphBuilder::CreateJoin(HBasicBlock* first,
3015 HBasicBlock* second, 3018 HBasicBlock* second,
3016 BailoutId join_id) { 3019 BailoutId join_id) {
3017 if (first == NULL) { 3020 if (first == NULL) {
3018 return second; 3021 return second;
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after
3067 3070
3068 HBasicBlock* HOptimizedGraphBuilder::BuildLoopEntry( 3071 HBasicBlock* HOptimizedGraphBuilder::BuildLoopEntry(
3069 IterationStatement* statement) { 3072 IterationStatement* statement) {
3070 HBasicBlock* loop_entry = osr()->HasOsrEntryAt(statement) 3073 HBasicBlock* loop_entry = osr()->HasOsrEntryAt(statement)
3071 ? osr()->BuildOsrLoopEntry(statement) 3074 ? osr()->BuildOsrLoopEntry(statement)
3072 : BuildLoopEntry(); 3075 : BuildLoopEntry();
3073 return loop_entry; 3076 return loop_entry;
3074 } 3077 }
3075 3078
3076 3079
3077 void HBasicBlock::FinishExit(HControlInstruction* instruction, int position) { 3080 void HBasicBlock::FinishExit(HControlInstruction* instruction,
3081 HSourcePosition position) {
3078 Finish(instruction, position); 3082 Finish(instruction, position);
3079 ClearEnvironment(); 3083 ClearEnvironment();
3080 } 3084 }
3081 3085
3082 3086
3083 HGraph::HGraph(CompilationInfo* info) 3087 HGraph::HGraph(CompilationInfo* info)
3084 : isolate_(info->isolate()), 3088 : isolate_(info->isolate()),
3085 next_block_id_(0), 3089 next_block_id_(0),
3086 entry_block_(NULL), 3090 entry_block_(NULL),
3087 blocks_(8, info->zone()), 3091 blocks_(8, info->zone()),
3088 values_(16, info->zone()), 3092 values_(16, info->zone()),
3089 phi_list_(NULL), 3093 phi_list_(NULL),
3090 uint32_instructions_(NULL), 3094 uint32_instructions_(NULL),
3091 osr_(NULL), 3095 osr_(NULL),
3092 info_(info), 3096 info_(info),
3093 zone_(info->zone()), 3097 zone_(info->zone()),
3094 is_recursive_(false), 3098 is_recursive_(false),
3095 use_optimistic_licm_(false), 3099 use_optimistic_licm_(false),
3096 depends_on_empty_array_proto_elements_(false), 3100 depends_on_empty_array_proto_elements_(false),
3097 type_change_checksum_(0), 3101 type_change_checksum_(0),
3098 maximum_environment_size_(0), 3102 maximum_environment_size_(0),
3099 no_side_effects_scope_count_(0), 3103 no_side_effects_scope_count_(0),
3100 disallow_adding_new_values_(false) { 3104 disallow_adding_new_values_(false),
3105 next_inline_id_(0),
3106 inlined_functions_(5, info->zone()) {
3101 if (info->IsStub()) { 3107 if (info->IsStub()) {
3102 HydrogenCodeStub* stub = info->code_stub(); 3108 HydrogenCodeStub* stub = info->code_stub();
3103 CodeStubInterfaceDescriptor* descriptor = 3109 CodeStubInterfaceDescriptor* descriptor =
3104 stub->GetInterfaceDescriptor(isolate_); 3110 stub->GetInterfaceDescriptor(isolate_);
3105 start_environment_ = 3111 start_environment_ =
3106 new(zone_) HEnvironment(zone_, descriptor->environment_length()); 3112 new(zone_) HEnvironment(zone_, descriptor->environment_length());
3107 } else { 3113 } else {
3114 TraceInlinedFunction(info->shared_info(), HSourcePosition::Unknown());
3108 start_environment_ = 3115 start_environment_ =
3109 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_); 3116 new(zone_) HEnvironment(NULL, info->scope(), info->closure(), zone_);
3110 } 3117 }
3111 start_environment_->set_ast_id(BailoutId::FunctionEntry()); 3118 start_environment_->set_ast_id(BailoutId::FunctionEntry());
3112 entry_block_ = CreateBasicBlock(); 3119 entry_block_ = CreateBasicBlock();
3113 entry_block_->SetInitialEnvironment(start_environment_); 3120 entry_block_->SetInitialEnvironment(start_environment_);
3114 } 3121 }
3115 3122
3116 3123
3117 HBasicBlock* HGraph::CreateBasicBlock() { 3124 HBasicBlock* HGraph::CreateBasicBlock() {
3118 HBasicBlock* result = new(zone()) HBasicBlock(this); 3125 HBasicBlock* result = new(zone()) HBasicBlock(this);
3119 blocks_.Add(result, zone()); 3126 blocks_.Add(result, zone());
3120 return result; 3127 return result;
3121 } 3128 }
3122 3129
3123 3130
3124 void HGraph::FinalizeUniqueness() { 3131 void HGraph::FinalizeUniqueness() {
3125 DisallowHeapAllocation no_gc; 3132 DisallowHeapAllocation no_gc;
3126 ASSERT(!OptimizingCompilerThread::IsOptimizerThread(isolate())); 3133 ASSERT(!OptimizingCompilerThread::IsOptimizerThread(isolate()));
3127 for (int i = 0; i < blocks()->length(); ++i) { 3134 for (int i = 0; i < blocks()->length(); ++i) {
3128 for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) { 3135 for (HInstructionIterator it(blocks()->at(i)); !it.Done(); it.Advance()) {
3129 it.Current()->FinalizeUniqueness(); 3136 it.Current()->FinalizeUniqueness();
3130 } 3137 }
3131 } 3138 }
3132 } 3139 }
3133 3140
3134 3141
3142 int HGraph::TraceInlinedFunction(
3143 Handle<SharedFunctionInfo> shared,
3144 HSourcePosition position) {
3145 if (!FLAG_hydrogen_track_positions) {
3146 return 0;
3147 }
3148
3149 int id = 0;
3150 for (; id < inlined_functions_.length(); id++) {
3151 if (inlined_functions_[id].shared().is_identical_to(shared)) {
3152 break;
3153 }
3154 }
3155
3156 if (id == inlined_functions_.length()) {
3157 inlined_functions_.Add(InlinedFunctionInfo(shared), zone());
3158
3159 if (!shared->script()->IsUndefined()) {
3160 Handle<Script> script(Script::cast(shared->script()));
3161 if (!script->source()->IsUndefined()) {
3162 CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer());
3163 PrintF(tracing_scope.file(),
3164 "--- FUNCTION SOURCE (%s) id{%d,%d} ---\n",
3165 shared->DebugName()->ToCString().get(),
3166 info()->optimization_id(),
3167 id);
3168
3169 {
3170 ConsStringIteratorOp op;
3171 StringCharacterStream stream(String::cast(script->source()),
3172 &op,
3173 shared->start_position());
3174 // fun->end_position() points to the last character in the stream. We
3175 // need to compensate by adding one to calculate the length.
3176 int source_len =
3177 shared->end_position() - shared->start_position() + 1;
3178 for (int i = 0; i < source_len; i++) {
3179 if (stream.HasMore()) {
3180 PrintF(tracing_scope.file(), "%c", stream.GetNext());
3181 }
3182 }
3183 }
3184
3185 PrintF(tracing_scope.file(), "\n--- END ---\n");
3186 }
3187 }
3188 }
3189
3190 int inline_id = next_inline_id_++;
3191
3192 if (inline_id != 0) {
3193 CodeTracer::Scope tracing_scope(isolate()->GetCodeTracer());
3194 PrintF(tracing_scope.file(), "INLINE (%s) id{%d,%d} AS %d AT ",
3195 shared->DebugName()->ToCString().get(),
3196 info()->optimization_id(),
3197 id,
3198 inline_id);
3199 position.PrintTo(tracing_scope.file());
3200 PrintF(tracing_scope.file(), "\n");
3201 }
3202
3203 return inline_id;
3204 }
3205
3206
3207 int HGraph::SourcePositionToScriptPosition(HSourcePosition pos) {
3208 if (!FLAG_hydrogen_track_positions || pos.IsUnknown()) {
3209 return pos.raw();
3210 }
3211
3212 return inlined_functions_[pos.inlining_id()].start_position() +
3213 pos.position();
3214 }
3215
3216
3135 // Block ordering was implemented with two mutually recursive methods, 3217 // Block ordering was implemented with two mutually recursive methods,
3136 // HGraph::Postorder and HGraph::PostorderLoopBlocks. 3218 // HGraph::Postorder and HGraph::PostorderLoopBlocks.
3137 // The recursion could lead to stack overflow so the algorithm has been 3219 // The recursion could lead to stack overflow so the algorithm has been
3138 // implemented iteratively. 3220 // implemented iteratively.
3139 // At a high level the algorithm looks like this: 3221 // At a high level the algorithm looks like this:
3140 // 3222 //
3141 // Postorder(block, loop_header) : { 3223 // Postorder(block, loop_header) : {
3142 // if (block has already been visited or is of another loop) return; 3224 // if (block has already been visited or is of another loop) return;
3143 // mark block as visited; 3225 // mark block as visited;
3144 // if (block is a loop header) { 3226 // if (block is a loop header) {
(...skipping 358 matching lines...) Expand 10 before | Expand all | Expand 10 after
3503 phi_list_->Add(phi, zone()); 3585 phi_list_->Add(phi, zone());
3504 } 3586 }
3505 } 3587 }
3506 } 3588 }
3507 3589
3508 3590
3509 // Implementation of utility class to encapsulate the translation state for 3591 // Implementation of utility class to encapsulate the translation state for
3510 // a (possibly inlined) function. 3592 // a (possibly inlined) function.
3511 FunctionState::FunctionState(HOptimizedGraphBuilder* owner, 3593 FunctionState::FunctionState(HOptimizedGraphBuilder* owner,
3512 CompilationInfo* info, 3594 CompilationInfo* info,
3513 InliningKind inlining_kind) 3595 InliningKind inlining_kind,
3596 int inlining_id)
3514 : owner_(owner), 3597 : owner_(owner),
3515 compilation_info_(info), 3598 compilation_info_(info),
3516 call_context_(NULL), 3599 call_context_(NULL),
3517 inlining_kind_(inlining_kind), 3600 inlining_kind_(inlining_kind),
3518 function_return_(NULL), 3601 function_return_(NULL),
3519 test_context_(NULL), 3602 test_context_(NULL),
3520 entry_(NULL), 3603 entry_(NULL),
3521 arguments_object_(NULL), 3604 arguments_object_(NULL),
3522 arguments_elements_(NULL), 3605 arguments_elements_(NULL),
3606 inlining_id_(inlining_id),
3607 outer_source_position_(HSourcePosition::Unknown()),
3523 outer_(owner->function_state()) { 3608 outer_(owner->function_state()) {
3524 if (outer_ != NULL) { 3609 if (outer_ != NULL) {
3525 // State for an inline function. 3610 // State for an inline function.
3526 if (owner->ast_context()->IsTest()) { 3611 if (owner->ast_context()->IsTest()) {
3527 HBasicBlock* if_true = owner->graph()->CreateBasicBlock(); 3612 HBasicBlock* if_true = owner->graph()->CreateBasicBlock();
3528 HBasicBlock* if_false = owner->graph()->CreateBasicBlock(); 3613 HBasicBlock* if_false = owner->graph()->CreateBasicBlock();
3529 if_true->MarkAsInlineReturnTarget(owner->current_block()); 3614 if_true->MarkAsInlineReturnTarget(owner->current_block());
3530 if_false->MarkAsInlineReturnTarget(owner->current_block()); 3615 if_false->MarkAsInlineReturnTarget(owner->current_block());
3531 TestContext* outer_test_context = TestContext::cast(owner->ast_context()); 3616 TestContext* outer_test_context = TestContext::cast(owner->ast_context());
3532 Expression* cond = outer_test_context->condition(); 3617 Expression* cond = outer_test_context->condition();
3533 // The AstContext constructor pushed on the context stack. This newed 3618 // The AstContext constructor pushed on the context stack. This newed
3534 // instance is the reason that AstContext can't be BASE_EMBEDDED. 3619 // instance is the reason that AstContext can't be BASE_EMBEDDED.
3535 test_context_ = new TestContext(owner, cond, if_true, if_false); 3620 test_context_ = new TestContext(owner, cond, if_true, if_false);
3536 } else { 3621 } else {
3537 function_return_ = owner->graph()->CreateBasicBlock(); 3622 function_return_ = owner->graph()->CreateBasicBlock();
3538 function_return()->MarkAsInlineReturnTarget(owner->current_block()); 3623 function_return()->MarkAsInlineReturnTarget(owner->current_block());
3539 } 3624 }
3540 // Set this after possibly allocating a new TestContext above. 3625 // Set this after possibly allocating a new TestContext above.
3541 call_context_ = owner->ast_context(); 3626 call_context_ = owner->ast_context();
3542 } 3627 }
3543 3628
3544 // Push on the state stack. 3629 // Push on the state stack.
3545 owner->set_function_state(this); 3630 owner->set_function_state(this);
3631
3632 if (FLAG_hydrogen_track_positions) {
3633 outer_source_position_ = owner->source_position();
3634 owner->EnterInlinedSource(
3635 info->shared_info()->start_position(),
3636 inlining_id);
3637 owner->SetSourcePosition(info->shared_info()->start_position());
3638 }
3546 } 3639 }
3547 3640
3548 3641
3549 FunctionState::~FunctionState() { 3642 FunctionState::~FunctionState() {
3550 delete test_context_; 3643 delete test_context_;
3551 owner_->set_function_state(outer_); 3644 owner_->set_function_state(outer_);
3645
3646 if (FLAG_hydrogen_track_positions) {
3647 owner_->set_source_position(outer_source_position_);
3648 owner_->EnterInlinedSource(
3649 outer_->compilation_info()->shared_info()->start_position(),
3650 outer_->inlining_id());
3651 }
3552 } 3652 }
3553 3653
3554 3654
3555 // Implementation of utility classes to represent an expression's context in 3655 // Implementation of utility classes to represent an expression's context in
3556 // the AST. 3656 // the AST.
3557 AstContext::AstContext(HOptimizedGraphBuilder* owner, Expression::Context kind) 3657 AstContext::AstContext(HOptimizedGraphBuilder* owner, Expression::Context kind)
3558 : owner_(owner), 3658 : owner_(owner),
3559 kind_(kind), 3659 kind_(kind),
3560 outer_(owner->ast_context()), 3660 outer_(owner->ast_context()),
3561 for_typeof_(false) { 3661 for_typeof_(false) {
(...skipping 792 matching lines...) Expand 10 before | Expand all | Expand 10 after
4354 } 4454 }
4355 4455
4356 // Generate a compare and branch. 4456 // Generate a compare and branch.
4357 CHECK_ALIVE(VisitForValue(clause->label())); 4457 CHECK_ALIVE(VisitForValue(clause->label()));
4358 HValue* label_value = Pop(); 4458 HValue* label_value = Pop();
4359 4459
4360 Type* label_type = clause->label()->bounds().lower; 4460 Type* label_type = clause->label()->bounds().lower;
4361 Type* combined_type = clause->compare_type(); 4461 Type* combined_type = clause->compare_type();
4362 HControlInstruction* compare = BuildCompareInstruction( 4462 HControlInstruction* compare = BuildCompareInstruction(
4363 Token::EQ_STRICT, tag_value, label_value, tag_type, label_type, 4463 Token::EQ_STRICT, tag_value, label_value, tag_type, label_type,
4364 combined_type, stmt->tag()->position(), clause->label()->position(), 4464 combined_type,
4465 ScriptPositionToSourcePosition(stmt->tag()->position()),
4466 ScriptPositionToSourcePosition(clause->label()->position()),
4365 clause->id()); 4467 clause->id());
4366 4468
4367 HBasicBlock* next_test_block = graph()->CreateBasicBlock(); 4469 HBasicBlock* next_test_block = graph()->CreateBasicBlock();
4368 HBasicBlock* body_block = graph()->CreateBasicBlock(); 4470 HBasicBlock* body_block = graph()->CreateBasicBlock();
4369 body_blocks.Add(body_block, zone()); 4471 body_blocks.Add(body_block, zone());
4370 compare->SetSuccessorAt(0, body_block); 4472 compare->SetSuccessorAt(0, body_block);
4371 compare->SetSuccessorAt(1, next_test_block); 4473 compare->SetSuccessorAt(1, next_test_block);
4372 FinishCurrentBlock(compare); 4474 FinishCurrentBlock(compare);
4373 4475
4374 set_current_block(body_block); 4476 set_current_block(body_block);
(...skipping 1746 matching lines...) Expand 10 before | Expand all | Expand 10 after
6121 ASSERT(!HasStackOverflow()); 6223 ASSERT(!HasStackOverflow());
6122 ASSERT(current_block() != NULL); 6224 ASSERT(current_block() != NULL);
6123 ASSERT(current_block()->HasPredecessor()); 6225 ASSERT(current_block()->HasPredecessor());
6124 // We don't optimize functions with invalid left-hand sides in 6226 // We don't optimize functions with invalid left-hand sides in
6125 // assignments, count operations, or for-in. Consequently throw can 6227 // assignments, count operations, or for-in. Consequently throw can
6126 // currently only occur in an effect context. 6228 // currently only occur in an effect context.
6127 ASSERT(ast_context()->IsEffect()); 6229 ASSERT(ast_context()->IsEffect());
6128 CHECK_ALIVE(VisitForValue(expr->exception())); 6230 CHECK_ALIVE(VisitForValue(expr->exception()));
6129 6231
6130 HValue* value = environment()->Pop(); 6232 HValue* value = environment()->Pop();
6131 if (!FLAG_emit_opt_code_positions) SetSourcePosition(expr->position()); 6233 if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position());
6132 Add<HPushArgument>(value); 6234 Add<HPushArgument>(value);
6133 Add<HCallRuntime>(isolate()->factory()->empty_string(), 6235 Add<HCallRuntime>(isolate()->factory()->empty_string(),
6134 Runtime::FunctionForId(Runtime::kThrow), 1); 6236 Runtime::FunctionForId(Runtime::kThrow), 1);
6135 Add<HSimulate>(expr->id()); 6237 Add<HSimulate>(expr->id());
6136 6238
6137 // If the throw definitely exits the function, we can finish with a dummy 6239 // If the throw definitely exits the function, we can finish with a dummy
6138 // control flow at this point. This is not the case if the throw is inside 6240 // control flow at this point. This is not the case if the throw is inside
6139 // an inlined function which may be replaced. 6241 // an inlined function which may be replaced.
6140 if (call_context() == NULL) { 6242 if (call_context() == NULL) {
6141 FinishExitCurrentBlock(New<HAbnormalExit>()); 6243 FinishExitCurrentBlock(New<HAbnormalExit>());
(...skipping 956 matching lines...) Expand 10 before | Expand all | Expand 10 after
7098 int nodes_added = target_shared->ast_node_count(); 7200 int nodes_added = target_shared->ast_node_count();
7099 return nodes_added; 7201 return nodes_added;
7100 } 7202 }
7101 7203
7102 7204
7103 bool HOptimizedGraphBuilder::TryInline(Handle<JSFunction> target, 7205 bool HOptimizedGraphBuilder::TryInline(Handle<JSFunction> target,
7104 int arguments_count, 7206 int arguments_count,
7105 HValue* implicit_return_value, 7207 HValue* implicit_return_value,
7106 BailoutId ast_id, 7208 BailoutId ast_id,
7107 BailoutId return_id, 7209 BailoutId return_id,
7108 InliningKind inlining_kind) { 7210 InliningKind inlining_kind,
7211 HSourcePosition position) {
7109 int nodes_added = InliningAstSize(target); 7212 int nodes_added = InliningAstSize(target);
7110 if (nodes_added == kNotInlinable) return false; 7213 if (nodes_added == kNotInlinable) return false;
7111 7214
7112 Handle<JSFunction> caller = current_info()->closure(); 7215 Handle<JSFunction> caller = current_info()->closure();
7113 7216
7114 if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) { 7217 if (nodes_added > Min(FLAG_max_inlined_nodes, kUnlimitedMaxInlinedNodes)) {
7115 TraceInline(target, caller, "target AST is too large [early]"); 7218 TraceInline(target, caller, "target AST is too large [early]");
7116 return false; 7219 return false;
7117 } 7220 }
7118 7221
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after
7230 } 7333 }
7231 7334
7232 // ---------------------------------------------------------------- 7335 // ----------------------------------------------------------------
7233 // After this point, we've made a decision to inline this function (so 7336 // After this point, we've made a decision to inline this function (so
7234 // TryInline should always return true). 7337 // TryInline should always return true).
7235 7338
7236 // Type-check the inlined function. 7339 // Type-check the inlined function.
7237 ASSERT(target_shared->has_deoptimization_support()); 7340 ASSERT(target_shared->has_deoptimization_support());
7238 AstTyper::Run(&target_info); 7341 AstTyper::Run(&target_info);
7239 7342
7343 int function_id = graph()->TraceInlinedFunction(target_shared, position);
7344
7240 // Save the pending call context. Set up new one for the inlined function. 7345 // Save the pending call context. Set up new one for the inlined function.
7241 // The function state is new-allocated because we need to delete it 7346 // The function state is new-allocated because we need to delete it
7242 // in two different places. 7347 // in two different places.
7243 FunctionState* target_state = new FunctionState( 7348 FunctionState* target_state = new FunctionState(
7244 this, &target_info, inlining_kind); 7349 this, &target_info, inlining_kind, function_id);
7245 7350
7246 HConstant* undefined = graph()->GetConstantUndefined(); 7351 HConstant* undefined = graph()->GetConstantUndefined();
7247 7352
7248 HEnvironment* inner_env = 7353 HEnvironment* inner_env =
7249 environment()->CopyForInlining(target, 7354 environment()->CopyForInlining(target,
7250 arguments_count, 7355 arguments_count,
7251 function, 7356 function,
7252 undefined, 7357 undefined,
7253 function_state()->inlining_kind()); 7358 function_state()->inlining_kind());
7254 7359
(...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after
7381 return true; 7486 return true;
7382 } 7487 }
7383 7488
7384 7489
7385 bool HOptimizedGraphBuilder::TryInlineCall(Call* expr) { 7490 bool HOptimizedGraphBuilder::TryInlineCall(Call* expr) {
7386 return TryInline(expr->target(), 7491 return TryInline(expr->target(),
7387 expr->arguments()->length(), 7492 expr->arguments()->length(),
7388 NULL, 7493 NULL,
7389 expr->id(), 7494 expr->id(),
7390 expr->ReturnId(), 7495 expr->ReturnId(),
7391 NORMAL_RETURN); 7496 NORMAL_RETURN,
7497 ScriptPositionToSourcePosition(expr->position()));
7392 } 7498 }
7393 7499
7394 7500
7395 bool HOptimizedGraphBuilder::TryInlineConstruct(CallNew* expr, 7501 bool HOptimizedGraphBuilder::TryInlineConstruct(CallNew* expr,
7396 HValue* implicit_return_value) { 7502 HValue* implicit_return_value) {
7397 return TryInline(expr->target(), 7503 return TryInline(expr->target(),
7398 expr->arguments()->length(), 7504 expr->arguments()->length(),
7399 implicit_return_value, 7505 implicit_return_value,
7400 expr->id(), 7506 expr->id(),
7401 expr->ReturnId(), 7507 expr->ReturnId(),
7402 CONSTRUCT_CALL_RETURN); 7508 CONSTRUCT_CALL_RETURN,
7509 ScriptPositionToSourcePosition(expr->position()));
7403 } 7510 }
7404 7511
7405 7512
7406 bool HOptimizedGraphBuilder::TryInlineGetter(Handle<JSFunction> getter, 7513 bool HOptimizedGraphBuilder::TryInlineGetter(Handle<JSFunction> getter,
7407 Handle<Map> receiver_map, 7514 Handle<Map> receiver_map,
7408 BailoutId ast_id, 7515 BailoutId ast_id,
7409 BailoutId return_id) { 7516 BailoutId return_id) {
7410 if (TryInlineApiGetter(getter, receiver_map, ast_id)) return true; 7517 if (TryInlineApiGetter(getter, receiver_map, ast_id)) return true;
7411 return TryInline(getter, 7518 return TryInline(getter,
7412 0, 7519 0,
7413 NULL, 7520 NULL,
7414 ast_id, 7521 ast_id,
7415 return_id, 7522 return_id,
7416 GETTER_CALL_RETURN); 7523 GETTER_CALL_RETURN,
7524 source_position());
7417 } 7525 }
7418 7526
7419 7527
7420 bool HOptimizedGraphBuilder::TryInlineSetter(Handle<JSFunction> setter, 7528 bool HOptimizedGraphBuilder::TryInlineSetter(Handle<JSFunction> setter,
7421 Handle<Map> receiver_map, 7529 Handle<Map> receiver_map,
7422 BailoutId id, 7530 BailoutId id,
7423 BailoutId assignment_id, 7531 BailoutId assignment_id,
7424 HValue* implicit_return_value) { 7532 HValue* implicit_return_value) {
7425 if (TryInlineApiSetter(setter, receiver_map, id)) return true; 7533 if (TryInlineApiSetter(setter, receiver_map, id)) return true;
7426 return TryInline(setter, 7534 return TryInline(setter,
7427 1, 7535 1,
7428 implicit_return_value, 7536 implicit_return_value,
7429 id, assignment_id, 7537 id, assignment_id,
7430 SETTER_CALL_RETURN); 7538 SETTER_CALL_RETURN,
7539 source_position());
7431 } 7540 }
7432 7541
7433 7542
7434 bool HOptimizedGraphBuilder::TryInlineApply(Handle<JSFunction> function, 7543 bool HOptimizedGraphBuilder::TryInlineApply(Handle<JSFunction> function,
7435 Call* expr, 7544 Call* expr,
7436 int arguments_count) { 7545 int arguments_count) {
7437 return TryInline(function, 7546 return TryInline(function,
7438 arguments_count, 7547 arguments_count,
7439 NULL, 7548 NULL,
7440 expr->id(), 7549 expr->id(),
7441 expr->ReturnId(), 7550 expr->ReturnId(),
7442 NORMAL_RETURN); 7551 NORMAL_RETURN,
7552 ScriptPositionToSourcePosition(expr->position()));
7443 } 7553 }
7444 7554
7445 7555
7446 bool HOptimizedGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr) { 7556 bool HOptimizedGraphBuilder::TryInlineBuiltinFunctionCall(Call* expr) {
7447 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false; 7557 if (!expr->target()->shared()->HasBuiltinFunctionId()) return false;
7448 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id(); 7558 BuiltinFunctionId id = expr->target()->shared()->builtin_function_id();
7449 switch (id) { 7559 switch (id) {
7450 case kMathExp: 7560 case kMathExp:
7451 if (!FLAG_fast_math) break; 7561 if (!FLAG_fast_math) break;
7452 // Fall through if FLAG_fast_math. 7562 // Fall through if FLAG_fast_math.
(...skipping 527 matching lines...) Expand 10 before | Expand all | Expand 10 after
7980 8090
7981 HValue* key = NULL; 8091 HValue* key = NULL;
7982 if (!prop->key()->IsPropertyName()) { 8092 if (!prop->key()->IsPropertyName()) {
7983 CHECK_ALIVE(VisitForValue(prop->key())); 8093 CHECK_ALIVE(VisitForValue(prop->key()));
7984 key = Pop(); 8094 key = Pop();
7985 } 8095 }
7986 8096
7987 CHECK_ALIVE(PushLoad(prop, receiver, key)); 8097 CHECK_ALIVE(PushLoad(prop, receiver, key));
7988 HValue* function = Pop(); 8098 HValue* function = Pop();
7989 8099
8100 if (FLAG_hydrogen_track_positions) SetSourcePosition(expr->position());
8101
7990 // Push the function under the receiver. 8102 // Push the function under the receiver.
7991 environment()->SetExpressionStackAt(0, function); 8103 environment()->SetExpressionStackAt(0, function);
7992 8104
7993 Push(receiver); 8105 Push(receiver);
7994 8106
7995 if (function->IsConstant() && 8107 if (function->IsConstant() &&
7996 HConstant::cast(function)->handle(isolate())->IsJSFunction()) { 8108 HConstant::cast(function)->handle(isolate())->IsJSFunction()) {
7997 Handle<JSFunction> known_function = Handle<JSFunction>::cast( 8109 Handle<JSFunction> known_function = Handle<JSFunction>::cast(
7998 HConstant::cast(function)->handle(isolate())); 8110 HConstant::cast(function)->handle(isolate()));
7999 expr->set_target(known_function); 8111 expr->set_target(known_function);
(...skipping 252 matching lines...) Expand 10 before | Expand all | Expand 10 after
8252 TraceInline(target, caller, NULL); 8364 TraceInline(target, caller, NULL);
8253 } 8365 }
8254 return inline_ok; 8366 return inline_ok;
8255 } 8367 }
8256 8368
8257 8369
8258 void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) { 8370 void HOptimizedGraphBuilder::VisitCallNew(CallNew* expr) {
8259 ASSERT(!HasStackOverflow()); 8371 ASSERT(!HasStackOverflow());
8260 ASSERT(current_block() != NULL); 8372 ASSERT(current_block() != NULL);
8261 ASSERT(current_block()->HasPredecessor()); 8373 ASSERT(current_block()->HasPredecessor());
8262 if (!FLAG_emit_opt_code_positions) SetSourcePosition(expr->position()); 8374 if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position());
8263 int argument_count = expr->arguments()->length() + 1; // Plus constructor. 8375 int argument_count = expr->arguments()->length() + 1; // Plus constructor.
8264 Factory* factory = isolate()->factory(); 8376 Factory* factory = isolate()->factory();
8265 8377
8266 // The constructor function is on the stack in the unoptimized code 8378 // The constructor function is on the stack in the unoptimized code
8267 // during evaluation of the arguments. 8379 // during evaluation of the arguments.
8268 CHECK_ALIVE(VisitForValue(expr->expression())); 8380 CHECK_ALIVE(VisitForValue(expr->expression()));
8269 HValue* function = Top(); 8381 HValue* function = Top();
8270 CHECK_ALIVE(VisitExpressions(expr->arguments())); 8382 CHECK_ALIVE(VisitExpressions(expr->arguments()));
8271 8383
8272 if (FLAG_inline_construct && 8384 if (FLAG_inline_construct &&
(...skipping 522 matching lines...) Expand 10 before | Expand all | Expand 10 after
8795 if (key != NULL) Push(key); 8907 if (key != NULL) Push(key);
8796 Push(value); 8908 Push(value);
8797 BuildStore(expr, prop, ast_id, return_id); 8909 BuildStore(expr, prop, ast_id, return_id);
8798 } 8910 }
8799 8911
8800 8912
8801 void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) { 8913 void HOptimizedGraphBuilder::VisitCountOperation(CountOperation* expr) {
8802 ASSERT(!HasStackOverflow()); 8914 ASSERT(!HasStackOverflow());
8803 ASSERT(current_block() != NULL); 8915 ASSERT(current_block() != NULL);
8804 ASSERT(current_block()->HasPredecessor()); 8916 ASSERT(current_block()->HasPredecessor());
8805 if (!FLAG_emit_opt_code_positions) SetSourcePosition(expr->position()); 8917 if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position());
8806 Expression* target = expr->expression(); 8918 Expression* target = expr->expression();
8807 VariableProxy* proxy = target->AsVariableProxy(); 8919 VariableProxy* proxy = target->AsVariableProxy();
8808 Property* prop = target->AsProperty(); 8920 Property* prop = target->AsProperty();
8809 if (proxy == NULL && prop == NULL) { 8921 if (proxy == NULL && prop == NULL) {
8810 return Bailout(kInvalidLhsInCountOperation); 8922 return Bailout(kInvalidLhsInCountOperation);
8811 } 8923 }
8812 8924
8813 // Match the full code generator stack by simulating an extra stack 8925 // Match the full code generator stack by simulating an extra stack
8814 // element for postfix operations in a non-effect context. The return 8926 // element for postfix operations in a non-effect context. The return
8815 // value is ToNumber(input). 8927 // value is ToNumber(input).
(...skipping 646 matching lines...) Expand 10 before | Expand all | Expand 10 after
9462 void HOptimizedGraphBuilder::VisitArithmeticExpression(BinaryOperation* expr) { 9574 void HOptimizedGraphBuilder::VisitArithmeticExpression(BinaryOperation* expr) {
9463 CHECK_ALIVE(VisitForValue(expr->left())); 9575 CHECK_ALIVE(VisitForValue(expr->left()));
9464 CHECK_ALIVE(VisitForValue(expr->right())); 9576 CHECK_ALIVE(VisitForValue(expr->right()));
9465 SetSourcePosition(expr->position()); 9577 SetSourcePosition(expr->position());
9466 HValue* right = Pop(); 9578 HValue* right = Pop();
9467 HValue* left = Pop(); 9579 HValue* left = Pop();
9468 HValue* result = 9580 HValue* result =
9469 BuildBinaryOperation(expr, left, right, 9581 BuildBinaryOperation(expr, left, right,
9470 ast_context()->IsEffect() ? NO_PUSH_BEFORE_SIMULATE 9582 ast_context()->IsEffect() ? NO_PUSH_BEFORE_SIMULATE
9471 : PUSH_BEFORE_SIMULATE); 9583 : PUSH_BEFORE_SIMULATE);
9472 if (FLAG_emit_opt_code_positions && result->IsBinaryOperation()) { 9584 if (FLAG_hydrogen_track_positions && result->IsBinaryOperation()) {
9473 HBinaryOperation::cast(result)->SetOperandPositions( 9585 HBinaryOperation::cast(result)->SetOperandPositions(
9474 zone(), expr->left()->position(), expr->right()->position()); 9586 zone(),
9587 ScriptPositionToSourcePosition(expr->left()->position()),
9588 ScriptPositionToSourcePosition(expr->right()->position()));
9475 } 9589 }
9476 return ast_context()->ReturnValue(result); 9590 return ast_context()->ReturnValue(result);
9477 } 9591 }
9478 9592
9479 9593
9480 void HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr, 9594 void HOptimizedGraphBuilder::HandleLiteralCompareTypeof(CompareOperation* expr,
9481 Expression* sub_expr, 9595 Expression* sub_expr,
9482 Handle<String> check) { 9596 Handle<String> check) {
9483 CHECK_ALIVE(VisitForTypeOf(sub_expr)); 9597 CHECK_ALIVE(VisitForTypeOf(sub_expr));
9484 SetSourcePosition(expr->position()); 9598 SetSourcePosition(expr->position());
(...skipping 13 matching lines...) Expand all
9498 (right->IsConstant() && 9612 (right->IsConstant() &&
9499 HConstant::cast(right)->handle(isolate)->IsBoolean())); 9613 HConstant::cast(right)->handle(isolate)->IsBoolean()));
9500 } 9614 }
9501 9615
9502 9616
9503 void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) { 9617 void HOptimizedGraphBuilder::VisitCompareOperation(CompareOperation* expr) {
9504 ASSERT(!HasStackOverflow()); 9618 ASSERT(!HasStackOverflow());
9505 ASSERT(current_block() != NULL); 9619 ASSERT(current_block() != NULL);
9506 ASSERT(current_block()->HasPredecessor()); 9620 ASSERT(current_block()->HasPredecessor());
9507 9621
9508 if (!FLAG_emit_opt_code_positions) SetSourcePosition(expr->position()); 9622 if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position());
9509 9623
9510 // Check for a few fast cases. The AST visiting behavior must be in sync 9624 // Check for a few fast cases. The AST visiting behavior must be in sync
9511 // with the full codegen: We don't push both left and right values onto 9625 // with the full codegen: We don't push both left and right values onto
9512 // the expression stack when one side is a special-case literal. 9626 // the expression stack when one side is a special-case literal.
9513 Expression* sub_expr = NULL; 9627 Expression* sub_expr = NULL;
9514 Handle<String> check; 9628 Handle<String> check;
9515 if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) { 9629 if (expr->IsLiteralCompareTypeof(&sub_expr, &check)) {
9516 return HandleLiteralCompareTypeof(expr, sub_expr, check); 9630 return HandleLiteralCompareTypeof(expr, sub_expr, check);
9517 } 9631 }
9518 if (expr->IsLiteralCompareUndefined(&sub_expr, isolate())) { 9632 if (expr->IsLiteralCompareUndefined(&sub_expr, isolate())) {
(...skipping 14 matching lines...) Expand all
9533 return ast_context()->ReturnControl(instr, expr->id()); 9647 return ast_context()->ReturnControl(instr, expr->id());
9534 } 9648 }
9535 9649
9536 Type* left_type = expr->left()->bounds().lower; 9650 Type* left_type = expr->left()->bounds().lower;
9537 Type* right_type = expr->right()->bounds().lower; 9651 Type* right_type = expr->right()->bounds().lower;
9538 Type* combined_type = expr->combined_type(); 9652 Type* combined_type = expr->combined_type();
9539 9653
9540 CHECK_ALIVE(VisitForValue(expr->left())); 9654 CHECK_ALIVE(VisitForValue(expr->left()));
9541 CHECK_ALIVE(VisitForValue(expr->right())); 9655 CHECK_ALIVE(VisitForValue(expr->right()));
9542 9656
9543 if (FLAG_emit_opt_code_positions) SetSourcePosition(expr->position()); 9657 if (FLAG_hydrogen_track_positions) SetSourcePosition(expr->position());
9544 9658
9545 HValue* right = Pop(); 9659 HValue* right = Pop();
9546 HValue* left = Pop(); 9660 HValue* left = Pop();
9547 Token::Value op = expr->op(); 9661 Token::Value op = expr->op();
9548 9662
9549 if (IsLiteralCompareBool(isolate(), left, op, right)) { 9663 if (IsLiteralCompareBool(isolate(), left, op, right)) {
9550 HCompareObjectEqAndBranch* result = 9664 HCompareObjectEqAndBranch* result =
9551 New<HCompareObjectEqAndBranch>(left, right); 9665 New<HCompareObjectEqAndBranch>(left, right);
9552 return ast_context()->ReturnControl(result, expr->id()); 9666 return ast_context()->ReturnControl(result, expr->id());
9553 } 9667 }
(...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after
9595 Add<HPushArgument>(left); 9709 Add<HPushArgument>(left);
9596 Add<HPushArgument>(right); 9710 Add<HPushArgument>(right);
9597 // TODO(olivf) InvokeFunction produces a check for the parameter count, 9711 // TODO(olivf) InvokeFunction produces a check for the parameter count,
9598 // even though we are certain to pass the correct number of arguments here. 9712 // even though we are certain to pass the correct number of arguments here.
9599 HInstruction* result = New<HInvokeFunction>(function, 2); 9713 HInstruction* result = New<HInvokeFunction>(function, 2);
9600 return ast_context()->ReturnInstruction(result, expr->id()); 9714 return ast_context()->ReturnInstruction(result, expr->id());
9601 } 9715 }
9602 9716
9603 HControlInstruction* compare = BuildCompareInstruction( 9717 HControlInstruction* compare = BuildCompareInstruction(
9604 op, left, right, left_type, right_type, combined_type, 9718 op, left, right, left_type, right_type, combined_type,
9605 expr->left()->position(), expr->right()->position(), expr->id()); 9719 ScriptPositionToSourcePosition(expr->left()->position()),
9720 ScriptPositionToSourcePosition(expr->right()->position()),
9721 expr->id());
9606 if (compare == NULL) return; // Bailed out. 9722 if (compare == NULL) return; // Bailed out.
9607 return ast_context()->ReturnControl(compare, expr->id()); 9723 return ast_context()->ReturnControl(compare, expr->id());
9608 } 9724 }
9609 9725
9610 9726
9611 HControlInstruction* HOptimizedGraphBuilder::BuildCompareInstruction( 9727 HControlInstruction* HOptimizedGraphBuilder::BuildCompareInstruction(
9612 Token::Value op, 9728 Token::Value op,
9613 HValue* left, 9729 HValue* left,
9614 HValue* right, 9730 HValue* right,
9615 Type* left_type, 9731 Type* left_type,
9616 Type* right_type, 9732 Type* right_type,
9617 Type* combined_type, 9733 Type* combined_type,
9618 int left_position, 9734 HSourcePosition left_position,
9619 int right_position, 9735 HSourcePosition right_position,
9620 BailoutId bailout_id) { 9736 BailoutId bailout_id) {
9621 // Cases handled below depend on collected type feedback. They should 9737 // Cases handled below depend on collected type feedback. They should
9622 // soft deoptimize when there is no type feedback. 9738 // soft deoptimize when there is no type feedback.
9623 if (combined_type->Is(Type::None())) { 9739 if (combined_type->Is(Type::None())) {
9624 Add<HDeoptimize>("Insufficient type feedback for combined type " 9740 Add<HDeoptimize>("Insufficient type feedback for combined type "
9625 "of binary operation", 9741 "of binary operation",
9626 Deoptimizer::SOFT); 9742 Deoptimizer::SOFT);
9627 combined_type = left_type = right_type = Type::Any(zone()); 9743 combined_type = left_type = right_type = Type::Any(zone());
9628 } 9744 }
9629 9745
9630 Representation left_rep = Representation::FromType(left_type); 9746 Representation left_rep = Representation::FromType(left_type);
9631 Representation right_rep = Representation::FromType(right_type); 9747 Representation right_rep = Representation::FromType(right_type);
9632 Representation combined_rep = Representation::FromType(combined_type); 9748 Representation combined_rep = Representation::FromType(combined_type);
9633 9749
9634 if (combined_type->Is(Type::Receiver())) { 9750 if (combined_type->Is(Type::Receiver())) {
9635 if (Token::IsEqualityOp(op)) { 9751 if (Token::IsEqualityOp(op)) {
9636 // Can we get away with map check and not instance type check? 9752 // Can we get away with map check and not instance type check?
9637 HValue* operand_to_check = 9753 HValue* operand_to_check =
9638 left->block()->block_id() < right->block()->block_id() ? left : right; 9754 left->block()->block_id() < right->block()->block_id() ? left : right;
9639 if (combined_type->IsClass()) { 9755 if (combined_type->IsClass()) {
9640 Handle<Map> map = combined_type->AsClass(); 9756 Handle<Map> map = combined_type->AsClass();
9641 AddCheckMap(operand_to_check, map); 9757 AddCheckMap(operand_to_check, map);
9642 HCompareObjectEqAndBranch* result = 9758 HCompareObjectEqAndBranch* result =
9643 New<HCompareObjectEqAndBranch>(left, right); 9759 New<HCompareObjectEqAndBranch>(left, right);
9644 if (FLAG_emit_opt_code_positions) { 9760 if (FLAG_hydrogen_track_positions) {
9645 result->set_operand_position(zone(), 0, left_position); 9761 result->set_operand_position(zone(), 0, left_position);
9646 result->set_operand_position(zone(), 1, right_position); 9762 result->set_operand_position(zone(), 1, right_position);
9647 } 9763 }
9648 return result; 9764 return result;
9649 } else { 9765 } else {
9650 BuildCheckHeapObject(operand_to_check); 9766 BuildCheckHeapObject(operand_to_check);
9651 Add<HCheckInstanceType>(operand_to_check, 9767 Add<HCheckInstanceType>(operand_to_check,
9652 HCheckInstanceType::IS_SPEC_OBJECT); 9768 HCheckInstanceType::IS_SPEC_OBJECT);
9653 HCompareObjectEqAndBranch* result = 9769 HCompareObjectEqAndBranch* result =
9654 New<HCompareObjectEqAndBranch>(left, right); 9770 New<HCompareObjectEqAndBranch>(left, right);
(...skipping 30 matching lines...) Expand all
9685 AddSimulate(bailout_id, REMOVABLE_SIMULATE); 9801 AddSimulate(bailout_id, REMOVABLE_SIMULATE);
9686 Drop(1); 9802 Drop(1);
9687 } 9803 }
9688 // TODO(jkummerow): Can we make this more efficient? 9804 // TODO(jkummerow): Can we make this more efficient?
9689 HBranch* branch = New<HBranch>(result); 9805 HBranch* branch = New<HBranch>(result);
9690 return branch; 9806 return branch;
9691 } else { 9807 } else {
9692 HCompareNumericAndBranch* result = 9808 HCompareNumericAndBranch* result =
9693 New<HCompareNumericAndBranch>(left, right, op); 9809 New<HCompareNumericAndBranch>(left, right, op);
9694 result->set_observed_input_representation(left_rep, right_rep); 9810 result->set_observed_input_representation(left_rep, right_rep);
9695 if (FLAG_emit_opt_code_positions) { 9811 if (FLAG_hydrogen_track_positions) {
9696 result->SetOperandPositions(zone(), left_position, right_position); 9812 result->SetOperandPositions(zone(), left_position, right_position);
9697 } 9813 }
9698 return result; 9814 return result;
9699 } 9815 }
9700 } 9816 }
9701 } 9817 }
9702 9818
9703 9819
9704 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr, 9820 void HOptimizedGraphBuilder::HandleLiteralCompareNil(CompareOperation* expr,
9705 Expression* sub_expr, 9821 Expression* sub_expr,
9706 NilValue nil) { 9822 NilValue nil) {
9707 ASSERT(!HasStackOverflow()); 9823 ASSERT(!HasStackOverflow());
9708 ASSERT(current_block() != NULL); 9824 ASSERT(current_block() != NULL);
9709 ASSERT(current_block()->HasPredecessor()); 9825 ASSERT(current_block()->HasPredecessor());
9710 ASSERT(expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT); 9826 ASSERT(expr->op() == Token::EQ || expr->op() == Token::EQ_STRICT);
9711 if (!FLAG_emit_opt_code_positions) SetSourcePosition(expr->position()); 9827 if (!FLAG_hydrogen_track_positions) SetSourcePosition(expr->position());
9712 CHECK_ALIVE(VisitForValue(sub_expr)); 9828 CHECK_ALIVE(VisitForValue(sub_expr));
9713 HValue* value = Pop(); 9829 HValue* value = Pop();
9714 if (expr->op() == Token::EQ_STRICT) { 9830 if (expr->op() == Token::EQ_STRICT) {
9715 HConstant* nil_constant = nil == kNullValue 9831 HConstant* nil_constant = nil == kNullValue
9716 ? graph()->GetConstantNull() 9832 ? graph()->GetConstantNull()
9717 : graph()->GetConstantUndefined(); 9833 : graph()->GetConstantUndefined();
9718 HCompareObjectEqAndBranch* instr = 9834 HCompareObjectEqAndBranch* instr =
9719 New<HCompareObjectEqAndBranch>(value, nil_constant); 9835 New<HCompareObjectEqAndBranch>(value, nil_constant);
9720 return ast_context()->ReturnControl(instr, expr->id()); 9836 return ast_context()->ReturnControl(instr, expr->id());
9721 } else { 9837 } else {
(...skipping 1207 matching lines...) Expand 10 before | Expand all | Expand 10 after
10929 PrintTo(&trace); 11045 PrintTo(&trace);
10930 PrintF("%s", trace.ToCString().get()); 11046 PrintF("%s", trace.ToCString().get());
10931 } 11047 }
10932 11048
10933 11049
10934 void HTracer::TraceCompilation(CompilationInfo* info) { 11050 void HTracer::TraceCompilation(CompilationInfo* info) {
10935 Tag tag(this, "compilation"); 11051 Tag tag(this, "compilation");
10936 if (info->IsOptimizing()) { 11052 if (info->IsOptimizing()) {
10937 Handle<String> name = info->function()->debug_name(); 11053 Handle<String> name = info->function()->debug_name();
10938 PrintStringProperty("name", name->ToCString().get()); 11054 PrintStringProperty("name", name->ToCString().get());
10939 PrintStringProperty("method", name->ToCString().get()); 11055 PrintIndent();
11056 trace_.Add("method \"%s:%d\"\n",
11057 name->ToCString().get(),
11058 info->optimization_id());
10940 } else { 11059 } else {
10941 CodeStub::Major major_key = info->code_stub()->MajorKey(); 11060 CodeStub::Major major_key = info->code_stub()->MajorKey();
10942 PrintStringProperty("name", CodeStub::MajorName(major_key, false)); 11061 PrintStringProperty("name", CodeStub::MajorName(major_key, false));
10943 PrintStringProperty("method", "stub"); 11062 PrintStringProperty("method", "stub");
10944 } 11063 }
10945 PrintLongProperty("date", static_cast<int64_t>(OS::TimeCurrentMillis())); 11064 PrintLongProperty("date", static_cast<int64_t>(OS::TimeCurrentMillis()));
10946 } 11065 }
10947 11066
10948 11067
10949 void HTracer::TraceLithium(const char* name, LChunk* chunk) { 11068 void HTracer::TraceLithium(const char* name, LChunk* chunk) {
(...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after
11043 trace_.Add(" "); 11162 trace_.Add(" ");
11044 phi->PrintTo(&trace_); 11163 phi->PrintTo(&trace_);
11045 trace_.Add("\n"); 11164 trace_.Add("\n");
11046 } 11165 }
11047 } 11166 }
11048 11167
11049 { 11168 {
11050 Tag HIR_tag(this, "HIR"); 11169 Tag HIR_tag(this, "HIR");
11051 for (HInstructionIterator it(current); !it.Done(); it.Advance()) { 11170 for (HInstructionIterator it(current); !it.Done(); it.Advance()) {
11052 HInstruction* instruction = it.Current(); 11171 HInstruction* instruction = it.Current();
11053 int bci = FLAG_emit_opt_code_positions && instruction->has_position() ?
11054 instruction->position() : 0;
11055 int uses = instruction->UseCount(); 11172 int uses = instruction->UseCount();
11056 PrintIndent(); 11173 PrintIndent();
11057 trace_.Add("%d %d ", bci, uses); 11174 trace_.Add("0 %d ", uses);
11058 instruction->PrintNameTo(&trace_); 11175 instruction->PrintNameTo(&trace_);
11059 trace_.Add(" "); 11176 trace_.Add(" ");
11060 instruction->PrintTo(&trace_); 11177 instruction->PrintTo(&trace_);
11178 if (FLAG_hydrogen_track_positions &&
11179 instruction->has_position() &&
11180 instruction->position().raw() != 0) {
11181 const HSourcePosition pos = instruction->position();
11182 trace_.Add(" pos:");
11183 if (pos.inlining_id() != 0) {
11184 trace_.Add("%d_", pos.inlining_id());
11185 }
11186 trace_.Add("%d", pos.position());
11187 }
11061 trace_.Add(" <|@\n"); 11188 trace_.Add(" <|@\n");
11062 } 11189 }
11063 } 11190 }
11064 11191
11065 11192
11066 if (chunk != NULL) { 11193 if (chunk != NULL) {
11067 Tag LIR_tag(this, "LIR"); 11194 Tag LIR_tag(this, "LIR");
11068 int first_index = current->first_instruction_index(); 11195 int first_index = current->first_instruction_index();
11069 int last_index = current->last_instruction_index(); 11196 int last_index = current->last_instruction_index();
11070 if (first_index != -1 && last_index != -1) { 11197 if (first_index != -1 && last_index != -1) {
(...skipping 180 matching lines...) Expand 10 before | Expand all | Expand 10 after
11251 if (ShouldProduceTraceOutput()) { 11378 if (ShouldProduceTraceOutput()) {
11252 isolate()->GetHTracer()->TraceHydrogen(name(), graph_); 11379 isolate()->GetHTracer()->TraceHydrogen(name(), graph_);
11253 } 11380 }
11254 11381
11255 #ifdef DEBUG 11382 #ifdef DEBUG
11256 graph_->Verify(false); // No full verify. 11383 graph_->Verify(false); // No full verify.
11257 #endif 11384 #endif
11258 } 11385 }
11259 11386
11260 } } // namespace v8::internal 11387 } } // 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