OLD | NEW |
---|---|
1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2011, the Dart project authors. Please see the AUTHORS file |
2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
4 | 4 |
5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. | 5 #include "vm/globals.h" // Needed here to get TARGET_ARCH_IA32. |
6 #if defined(TARGET_ARCH_IA32) | 6 #if defined(TARGET_ARCH_IA32) |
7 | 7 |
8 #include "vm/code_generator.h" | 8 #include "vm/code_generator.h" |
9 | 9 |
10 #include "lib/error.h" | 10 #include "lib/error.h" |
(...skipping 253 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
264 | 264 |
265 // Pre entry code is called before the frame has been constructed: | 265 // Pre entry code is called before the frame has been constructed: |
266 // - check for stack overflow. | 266 // - check for stack overflow. |
267 // - optionally count function invocations. | 267 // - optionally count function invocations. |
268 // - optionally trigger optimizing compiler if invocation threshold has been | 268 // - optionally trigger optimizing compiler if invocation threshold has been |
269 // reached. | 269 // reached. |
270 // Note that first 5 bytes may be patched with a jump. | 270 // Note that first 5 bytes may be patched with a jump. |
271 // TODO(srdjan): Add check that no object is inlined in the first | 271 // TODO(srdjan): Add check that no object is inlined in the first |
272 // 5 bytes (length of a jump instruction). | 272 // 5 bytes (length of a jump instruction). |
273 void CodeGenerator::GeneratePreEntryCode() { | 273 void CodeGenerator::GeneratePreEntryCode() { |
274 // Stack overflow check. | |
275 __ cmpl(ESP, | |
276 Address::Absolute(Isolate::Current()->stack_limit_address())); | |
277 __ j(BELOW_EQUAL, &StubCode::StackOverflowLabel()); | |
278 // Do not optimize if: | 274 // Do not optimize if: |
279 // - we count invocations. | 275 // - we count invocations. |
280 // - optimization disabled via negative 'optimization_invocation_threshold; | 276 // - optimization disabled via negative 'optimization_invocation_threshold; |
281 // - function is marked as non-optimizable. | 277 // - function is marked as non-optimizable. |
282 // - type checks are enabled. | 278 // - type checks are enabled. |
283 const bool may_optimize = | 279 const bool may_optimize = |
284 !FLAG_report_invocation_count && | 280 !FLAG_report_invocation_count && |
285 (FLAG_optimization_invocation_threshold >= 0) && | 281 (FLAG_optimization_invocation_threshold >= 0) && |
286 !Isolate::Current()->debugger()->IsActive() && | 282 !Isolate::Current()->debugger()->IsActive() && |
287 parsed_function_.function().is_optimizable(); | 283 parsed_function_.function().is_optimizable(); |
288 // Count invocation and check. | 284 // Count invocation and check. |
289 if (FLAG_report_invocation_count || may_optimize) { | 285 if (FLAG_report_invocation_count || may_optimize) { |
286 // TODO(turnidge): It would be nice to remove this nops Right now | |
Ivan Posva
2011/12/14 23:59:50
"these nops. Right now"
turnidge
2011/12/15 21:30:07
Changed to "this nop", now that it is a single ins
| |
287 // we need it to make sure the function is still patchable. | |
288 __ nop(5); | |
290 const Function& function = | 289 const Function& function = |
291 Function::ZoneHandle(parsed_function_.function().raw()); | 290 Function::ZoneHandle(parsed_function_.function().raw()); |
292 __ LoadObject(EAX, function); | 291 __ LoadObject(EAX, function); |
293 __ movl(EBX, FieldAddress(EAX, Function::invocation_counter_offset())); | 292 __ movl(EBX, FieldAddress(EAX, Function::invocation_counter_offset())); |
294 __ incl(EBX); | 293 __ incl(EBX); |
295 if (may_optimize) { | 294 if (may_optimize) { |
296 __ cmpl(EBX, Immediate(FLAG_optimization_invocation_threshold)); | 295 __ cmpl(EBX, Immediate(FLAG_optimization_invocation_threshold)); |
297 __ j(GREATER, &StubCode::OptimizeInvokedFunctionLabel()); | 296 __ j(GREATER, &StubCode::OptimizeInvokedFunctionLabel()); |
298 } | 297 } |
299 __ movl(FieldAddress(EAX, Function::invocation_counter_offset()), EBX); | 298 __ movl(FieldAddress(EAX, Function::invocation_counter_offset()), EBX); |
(...skipping 407 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
707 // Initialize locals. | 706 // Initialize locals. |
708 // TODO(regis): For now, always unroll the init loop. Decide later above | 707 // TODO(regis): For now, always unroll the init loop. Decide later above |
709 // which threshold to implement a loop. | 708 // which threshold to implement a loop. |
710 // Consider emitting pushes instead of moves. | 709 // Consider emitting pushes instead of moves. |
711 for (int index = first_local_index; index > first_free_frame_index; index--) { | 710 for (int index = first_local_index; index > first_free_frame_index; index--) { |
712 if (index == first_local_index) { | 711 if (index == first_local_index) { |
713 __ movl(EAX, raw_null); | 712 __ movl(EAX, raw_null); |
714 } | 713 } |
715 __ movl(Address(EBP, index * kWordSize), EAX); | 714 __ movl(Address(EBP, index * kWordSize), EAX); |
716 } | 715 } |
716 | |
717 // Generate stack overflow check. | |
718 __ cmpl(ESP, | |
719 Address::Absolute(Isolate::Current()->stack_limit_address())); | |
720 Label no_stack_overflow; | |
721 __ j(ABOVE, &no_stack_overflow); | |
722 GenerateCallRuntime(AstNode::kNoId, 0, kStackOverflowRuntimeEntry); | |
723 __ Bind(&no_stack_overflow); | |
717 } | 724 } |
718 | 725 |
719 | 726 |
720 void CodeGenerator::GenerateReturnEpilog() { | 727 void CodeGenerator::GenerateReturnEpilog() { |
721 // Unchain the context(s) up to context level 0. | 728 // Unchain the context(s) up to context level 0. |
722 int context_level = state()->context_level(); | 729 int context_level = state()->context_level(); |
723 ASSERT(context_level >= 0); | 730 ASSERT(context_level >= 0); |
724 while (context_level-- > 0) { | 731 while (context_level-- > 0) { |
725 __ movl(CTX, FieldAddress(CTX, Context::parent_offset())); | 732 __ movl(CTX, FieldAddress(CTX, Context::parent_offset())); |
726 } | 733 } |
(...skipping 2016 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
2743 message_buffer, kMessageBufferSize, | 2750 message_buffer, kMessageBufferSize, |
2744 format, args); | 2751 format, args); |
2745 va_end(args); | 2752 va_end(args); |
2746 Isolate::Current()->long_jump_base()->Jump(1, message_buffer); | 2753 Isolate::Current()->long_jump_base()->Jump(1, message_buffer); |
2747 UNREACHABLE(); | 2754 UNREACHABLE(); |
2748 } | 2755 } |
2749 | 2756 |
2750 } // namespace dart | 2757 } // namespace dart |
2751 | 2758 |
2752 #endif // defined TARGET_ARCH_IA32 | 2759 #endif // defined TARGET_ARCH_IA32 |
OLD | NEW |