OLD | NEW |
---|---|
1 // Copyright 2013 the V8 project authors. All rights reserved. | 1 // Copyright 2013 the V8 project authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "src/crankshaft/lithium-codegen.h" | 5 #include "src/crankshaft/lithium-codegen.h" |
6 | 6 |
7 #include <sstream> | 7 #include <sstream> |
8 | 8 |
9 #if V8_TARGET_ARCH_IA32 | 9 #if V8_TARGET_ARCH_IA32 |
10 #include "src/crankshaft/ia32/lithium-ia32.h" // NOLINT | 10 #include "src/crankshaft/ia32/lithium-ia32.h" // NOLINT |
(...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
96 if (FLAG_code_comments && instr->HasInterestingComment(codegen)) { | 96 if (FLAG_code_comments && instr->HasInterestingComment(codegen)) { |
97 Comment(";;; <@%d,#%d> %s", | 97 Comment(";;; <@%d,#%d> %s", |
98 current_instruction_, | 98 current_instruction_, |
99 instr->hydrogen_value()->id(), | 99 instr->hydrogen_value()->id(), |
100 instr->Mnemonic()); | 100 instr->Mnemonic()); |
101 } | 101 } |
102 | 102 |
103 GenerateBodyInstructionPre(instr); | 103 GenerateBodyInstructionPre(instr); |
104 | 104 |
105 HValue* value = instr->hydrogen_value(); | 105 HValue* value = instr->hydrogen_value(); |
106 if (!value->position().IsUnknown()) { | 106 if (value->position().IsKnown()) { |
107 RecordAndWritePosition( | 107 RecordAndWritePosition(value->position()); |
108 chunk()->graph()->SourcePositionToScriptPosition(value->position())); | |
109 } | 108 } |
110 | 109 |
111 instr->CompileToNative(codegen); | 110 instr->CompileToNative(codegen); |
112 | 111 |
113 GenerateBodyInstructionPost(instr); | 112 GenerateBodyInstructionPost(instr); |
114 } | 113 } |
115 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size()); | 114 EnsureSpaceForLazyDeopt(Deoptimizer::patch_size()); |
116 last_lazy_deopt_pc_ = masm()->pc_offset(); | 115 last_lazy_deopt_pc_ = masm()->pc_offset(); |
117 return !is_aborted(); | 116 return !is_aborted(); |
118 } | 117 } |
(...skipping 15 matching lines...) Expand all Loading... | |
134 } | 133 } |
135 | 134 |
136 if (instr->HasEnvironment() && !instr->environment()->has_been_used()) { | 135 if (instr->HasEnvironment() && !instr->environment()->has_been_used()) { |
137 V8_Fatal(__FILE__, __LINE__, "unused environment for %s (%s)", | 136 V8_Fatal(__FILE__, __LINE__, "unused environment for %s (%s)", |
138 hinstr->Mnemonic(), instr->Mnemonic()); | 137 hinstr->Mnemonic(), instr->Mnemonic()); |
139 } | 138 } |
140 } | 139 } |
141 #endif | 140 #endif |
142 } | 141 } |
143 | 142 |
144 void LCodeGenBase::RecordAndWritePosition(int pos) { | 143 void LCodeGenBase::RecordAndWritePosition(SourcePosition pos) { |
145 if (pos == kNoSourcePosition) return; | 144 if (!pos.IsKnown()) return; |
146 source_position_table_builder_.AddPosition(masm_->pc_offset(), pos, false); | 145 source_position_table_builder_.AddPosition(masm_->pc_offset(), pos, false); |
147 } | 146 } |
148 | 147 |
149 void LCodeGenBase::Comment(const char* format, ...) { | 148 void LCodeGenBase::Comment(const char* format, ...) { |
150 if (!FLAG_code_comments) return; | 149 if (!FLAG_code_comments) return; |
151 char buffer[4 * KB]; | 150 char buffer[4 * KB]; |
152 StringBuilder builder(buffer, arraysize(buffer)); | 151 StringBuilder builder(buffer, arraysize(buffer)); |
153 va_list arguments; | 152 va_list arguments; |
154 va_start(arguments, format); | 153 va_start(arguments, format); |
155 builder.AddFormattedList(format, arguments); | 154 builder.AddFormattedList(format, arguments); |
156 va_end(arguments); | 155 va_end(arguments); |
157 | 156 |
158 // Copy the string before recording it in the assembler to avoid | 157 // Copy the string before recording it in the assembler to avoid |
159 // issues when the stack allocated buffer goes out of scope. | 158 // issues when the stack allocated buffer goes out of scope. |
160 size_t length = builder.position(); | 159 size_t length = builder.position(); |
161 Vector<char> copy = Vector<char>::New(static_cast<int>(length) + 1); | 160 Vector<char> copy = Vector<char>::New(static_cast<int>(length) + 1); |
162 MemCopy(copy.start(), builder.Finalize(), copy.length()); | 161 MemCopy(copy.start(), builder.Finalize(), copy.length()); |
163 masm()->RecordComment(copy.start()); | 162 masm()->RecordComment(copy.start()); |
164 } | 163 } |
165 | 164 |
166 | 165 |
167 void LCodeGenBase::DeoptComment(const Deoptimizer::DeoptInfo& deopt_info) { | 166 void LCodeGenBase::DeoptComment(const Deoptimizer::DeoptInfo& deopt_info) { |
168 SourcePosition position = deopt_info.position; | 167 SourcePosition position = deopt_info.position; |
169 int deopt_id = deopt_info.deopt_id; | 168 int deopt_id = deopt_info.deopt_id; |
170 int raw_position = position.IsUnknown() ? 0 : position.raw(); | 169 masm()->RecordDeoptReason(deopt_info.deopt_reason, position, deopt_id); |
171 masm()->RecordDeoptReason(deopt_info.deopt_reason, raw_position, deopt_id); | |
172 } | 170 } |
173 | 171 |
174 | 172 |
175 int LCodeGenBase::GetNextEmittedBlock() const { | 173 int LCodeGenBase::GetNextEmittedBlock() const { |
176 for (int i = current_block_ + 1; i < graph()->blocks()->length(); ++i) { | 174 for (int i = current_block_ + 1; i < graph()->blocks()->length(); ++i) { |
177 if (!graph()->blocks()->at(i)->IsReachable()) continue; | 175 if (!graph()->blocks()->at(i)->IsReachable()) continue; |
178 if (!chunk_->GetLabel(i)->HasReplacement()) return i; | 176 if (!chunk_->GetLabel(i)->HasReplacement()) return i; |
179 } | 177 } |
180 return -1; | 178 return -1; |
181 } | 179 } |
(...skipping 122 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
304 translation->StoreLiteral(closure_id); | 302 translation->StoreLiteral(closure_id); |
305 } | 303 } |
306 break; | 304 break; |
307 } | 305 } |
308 case STUB: | 306 case STUB: |
309 translation->BeginCompiledStubFrame(translation_size); | 307 translation->BeginCompiledStubFrame(translation_size); |
310 break; | 308 break; |
311 } | 309 } |
312 } | 310 } |
313 | 311 |
312 namespace { | |
313 | |
314 Handle<PodArray<InliningPosition>> CreateInliningPositions( | |
315 CompilationInfo* info) { | |
vogelheim
2016/11/07 17:53:27
Hrmm... This looks like an exact copy of CreateInl
Tobias Tebbi
2016/11/08 10:29:07
mstarzinger@ suggested this duplication, because w
| |
316 const CompilationInfo::InlinedFunctionList& inlined_functions = | |
317 info->inlined_functions(); | |
318 if (inlined_functions.size() == 0) | |
vogelheim
2016/11/07 17:53:27
nitpick: use braces if more than one line.
| |
319 return Handle<PodArray<InliningPosition>>::cast( | |
320 info->isolate()->factory()->empty_byte_array()); | |
321 Handle<PodArray<InliningPosition>> inl_positions = | |
322 PodArray<InliningPosition>::New( | |
323 info->isolate(), static_cast<int>(inlined_functions.size()), TENURED); | |
324 for (int i = 0; i < inlined_functions.size(); ++i) { | |
325 inl_positions->set(i, inlined_functions[i].position); | |
326 } | |
327 return inl_positions; | |
328 } | |
329 | |
330 } // namespace | |
314 | 331 |
315 void LCodeGenBase::PopulateDeoptimizationData(Handle<Code> code) { | 332 void LCodeGenBase::PopulateDeoptimizationData(Handle<Code> code) { |
316 int length = deoptimizations_.length(); | 333 int length = deoptimizations_.length(); |
317 if (length == 0) return; | 334 if (length == 0) return; |
318 Handle<DeoptimizationInputData> data = | 335 Handle<DeoptimizationInputData> data = |
319 DeoptimizationInputData::New(isolate(), length, TENURED); | 336 DeoptimizationInputData::New(isolate(), length, TENURED); |
320 | 337 |
321 Handle<ByteArray> translations = | 338 Handle<ByteArray> translations = |
322 translations_.CreateByteArray(isolate()->factory()); | 339 translations_.CreateByteArray(isolate()->factory()); |
323 data->SetTranslationByteArray(*translations); | 340 data->SetTranslationByteArray(*translations); |
(...skipping 11 matching lines...) Expand all Loading... | |
335 Handle<FixedArray> literals = | 352 Handle<FixedArray> literals = |
336 factory()->NewFixedArray(deoptimization_literals_.length(), TENURED); | 353 factory()->NewFixedArray(deoptimization_literals_.length(), TENURED); |
337 { | 354 { |
338 AllowDeferredHandleDereference copy_handles; | 355 AllowDeferredHandleDereference copy_handles; |
339 for (int i = 0; i < deoptimization_literals_.length(); i++) { | 356 for (int i = 0; i < deoptimization_literals_.length(); i++) { |
340 literals->set(i, *deoptimization_literals_[i]); | 357 literals->set(i, *deoptimization_literals_[i]); |
341 } | 358 } |
342 data->SetLiteralArray(*literals); | 359 data->SetLiteralArray(*literals); |
343 } | 360 } |
344 | 361 |
362 data->SetInliningPositions(*CreateInliningPositions(info_)); | |
363 | |
345 data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt())); | 364 data->SetOsrAstId(Smi::FromInt(info_->osr_ast_id().ToInt())); |
346 data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_)); | 365 data->SetOsrPcOffset(Smi::FromInt(osr_pc_offset_)); |
347 | 366 |
348 // Populate the deoptimization entries. | 367 // Populate the deoptimization entries. |
349 for (int i = 0; i < length; i++) { | 368 for (int i = 0; i < length; i++) { |
350 LEnvironment* env = deoptimizations_[i]; | 369 LEnvironment* env = deoptimizations_[i]; |
351 data->SetAstId(i, env->ast_id()); | 370 data->SetAstId(i, env->ast_id()); |
352 data->SetTranslationIndex(i, Smi::FromInt(env->translation_index())); | 371 data->SetTranslationIndex(i, Smi::FromInt(env->translation_index())); |
353 data->SetArgumentsStackHeight(i, | 372 data->SetArgumentsStackHeight(i, |
354 Smi::FromInt(env->arguments_stack_height())); | 373 Smi::FromInt(env->arguments_stack_height())); |
355 data->SetPc(i, Smi::FromInt(env->pc_offset())); | 374 data->SetPc(i, Smi::FromInt(env->pc_offset())); |
356 } | 375 } |
357 code->set_deoptimization_data(*data); | 376 code->set_deoptimization_data(*data); |
358 } | 377 } |
359 | 378 |
360 | 379 |
361 void LCodeGenBase::PopulateDeoptimizationLiteralsWithInlinedFunctions() { | 380 void LCodeGenBase::PopulateDeoptimizationLiteralsWithInlinedFunctions() { |
362 DCHECK_EQ(0, deoptimization_literals_.length()); | 381 DCHECK_EQ(0, deoptimization_literals_.length()); |
363 for (Handle<SharedFunctionInfo> function : chunk()->inlined_functions()) { | 382 for (CompilationInfo::InlinedFunctionHolder& inlined : |
364 DefineDeoptimizationLiteral(function); | 383 info()->inlined_functions()) { |
384 if (!inlined.shared_info.is_identical_to(info()->shared_info())) { | |
385 inlined.RegisterInlinedFunctionId(deoptimization_literals_.length()); | |
386 DefineDeoptimizationLiteral(inlined.shared_info); | |
387 } | |
365 } | 388 } |
366 inlined_function_count_ = deoptimization_literals_.length(); | 389 inlined_function_count_ = deoptimization_literals_.length(); |
367 | 390 |
368 // Define deoptimization literals for all unoptimized code objects of inlined | 391 // Define deoptimization literals for all unoptimized code objects of inlined |
369 // functions. This ensures unoptimized code is kept alive by optimized code. | 392 // functions. This ensures unoptimized code is kept alive by optimized code. |
370 AllowDeferredHandleDereference allow_shared_function_info_dereference; | 393 for (const CompilationInfo::InlinedFunctionHolder& inlined : |
371 for (Handle<SharedFunctionInfo> function : chunk()->inlined_functions()) { | 394 info()->inlined_functions()) { |
372 DefineDeoptimizationLiteral(handle(function->code())); | 395 if (!inlined.shared_info.is_identical_to(info()->shared_info())) { |
396 DefineDeoptimizationLiteral(inlined.inlined_code_object_root); | |
397 } | |
373 } | 398 } |
374 } | 399 } |
375 | 400 |
376 Deoptimizer::DeoptInfo LCodeGenBase::MakeDeoptInfo( | 401 Deoptimizer::DeoptInfo LCodeGenBase::MakeDeoptInfo( |
377 LInstruction* instr, DeoptimizeReason deopt_reason, int deopt_id) { | 402 LInstruction* instr, DeoptimizeReason deopt_reason, int deopt_id) { |
378 Deoptimizer::DeoptInfo deopt_info(instr->hydrogen_value()->position(), | 403 Deoptimizer::DeoptInfo deopt_info(instr->hydrogen_value()->position(), |
379 deopt_reason, deopt_id); | 404 deopt_reason, deopt_id); |
380 return deopt_info; | 405 return deopt_info; |
381 } | 406 } |
382 | 407 |
383 } // namespace internal | 408 } // namespace internal |
384 } // namespace v8 | 409 } // namespace v8 |
OLD | NEW |