| OLD | NEW |
| 1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
| 2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
| 3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
| 4 // met: | 4 // met: |
| 5 // | 5 // |
| 6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
| 7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
| 8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
| 9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
| 10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
| (...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 134 | 134 |
| 135 void HBasicBlock::RemovePhi(HPhi* phi) { | 135 void HBasicBlock::RemovePhi(HPhi* phi) { |
| 136 ASSERT(phi->block() == this); | 136 ASSERT(phi->block() == this); |
| 137 ASSERT(phis_.Contains(phi)); | 137 ASSERT(phis_.Contains(phi)); |
| 138 phi->Kill(); | 138 phi->Kill(); |
| 139 phis_.RemoveElement(phi); | 139 phis_.RemoveElement(phi); |
| 140 phi->SetBlock(NULL); | 140 phi->SetBlock(NULL); |
| 141 } | 141 } |
| 142 | 142 |
| 143 | 143 |
| 144 void HBasicBlock::AddInstruction(HInstruction* instr, int position) { | 144 void HBasicBlock::AddInstruction(HInstruction* instr, |
| 145 HSourcePosition position) { |
| 145 ASSERT(!IsStartBlock() || !IsFinished()); | 146 ASSERT(!IsStartBlock() || !IsFinished()); |
| 146 ASSERT(!instr->IsLinked()); | 147 ASSERT(!instr->IsLinked()); |
| 147 ASSERT(!IsFinished()); | 148 ASSERT(!IsFinished()); |
| 148 | 149 |
| 149 if (position != RelocInfo::kNoPosition) { | 150 if (!position.IsUnknown()) { |
| 150 instr->set_position(position); | 151 instr->set_position(position); |
| 151 } | 152 } |
| 152 if (first_ == NULL) { | 153 if (first_ == NULL) { |
| 153 ASSERT(last_environment() != NULL); | 154 ASSERT(last_environment() != NULL); |
| 154 ASSERT(!last_environment()->ast_id().IsNone()); | 155 ASSERT(!last_environment()->ast_id().IsNone()); |
| 155 HBlockEntry* entry = new(zone()) HBlockEntry(); | 156 HBlockEntry* entry = new(zone()) HBlockEntry(); |
| 156 entry->InitializeAsFirst(this); | 157 entry->InitializeAsFirst(this); |
| 157 if (position != RelocInfo::kNoPosition) { | 158 if (!position.IsUnknown()) { |
| 158 entry->set_position(position); | 159 entry->set_position(position); |
| 159 } else { | 160 } else { |
| 160 ASSERT(!FLAG_emit_opt_code_positions || | 161 ASSERT(!FLAG_hydrogen_track_positions || |
| 161 !graph()->info()->IsOptimizing()); | 162 !graph()->info()->IsOptimizing()); |
| 162 } | 163 } |
| 163 first_ = last_ = entry; | 164 first_ = last_ = entry; |
| 164 } | 165 } |
| 165 instr->InsertAfter(last_); | 166 instr->InsertAfter(last_); |
| 166 } | 167 } |
| 167 | 168 |
| 168 | 169 |
| 169 HPhi* HBasicBlock::AddNewPhi(int merged_index) { | 170 HPhi* HBasicBlock::AddNewPhi(int merged_index) { |
| 170 if (graph()->IsInsideNoSideEffectsScope()) { | 171 if (graph()->IsInsideNoSideEffectsScope()) { |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 !it.Done(); | 204 !it.Done(); |
| 204 it.Advance()) { | 205 it.Advance()) { |
| 205 int index = it.Current(); | 206 int index = it.Current(); |
| 206 instr->AddAssignedValue(index, environment->Lookup(index)); | 207 instr->AddAssignedValue(index, environment->Lookup(index)); |
| 207 } | 208 } |
| 208 environment->ClearHistory(); | 209 environment->ClearHistory(); |
| 209 return instr; | 210 return instr; |
| 210 } | 211 } |
| 211 | 212 |
| 212 | 213 |
| 213 void HBasicBlock::Finish(HControlInstruction* end, int position) { | 214 void HBasicBlock::Finish(HControlInstruction* end, HSourcePosition position) { |
| 214 ASSERT(!IsFinished()); | 215 ASSERT(!IsFinished()); |
| 215 AddInstruction(end, position); | 216 AddInstruction(end, position); |
| 216 end_ = end; | 217 end_ = end; |
| 217 for (HSuccessorIterator it(end); !it.Done(); it.Advance()) { | 218 for (HSuccessorIterator it(end); !it.Done(); it.Advance()) { |
| 218 it.Current()->RegisterPredecessor(this); | 219 it.Current()->RegisterPredecessor(this); |
| 219 } | 220 } |
| 220 } | 221 } |
| 221 | 222 |
| 222 | 223 |
| 223 void HBasicBlock::Goto(HBasicBlock* block, | 224 void HBasicBlock::Goto(HBasicBlock* block, |
| 224 int position, | 225 HSourcePosition position, |
| 225 FunctionState* state, | 226 FunctionState* state, |
| 226 bool add_simulate) { | 227 bool add_simulate) { |
| 227 bool drop_extra = state != NULL && | 228 bool drop_extra = state != NULL && |
| 228 state->inlining_kind() == 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |