| 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 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 203 if (FLAG_print_scopes && FLAG_print_ast) { | 203 if (FLAG_print_scopes && FLAG_print_ast) { |
| 204 // Print the function scope before code generation. | 204 // Print the function scope before code generation. |
| 205 AstPrinter::PrintFunctionScope(parsed_function_); | 205 AstPrinter::PrintFunctionScope(parsed_function_); |
| 206 } | 206 } |
| 207 if (FLAG_print_ast) { | 207 if (FLAG_print_ast) { |
| 208 // Print the function ast before code generation. | 208 // Print the function ast before code generation. |
| 209 AstPrinter::PrintFunctionNodes(parsed_function_); | 209 AstPrinter::PrintFunctionNodes(parsed_function_); |
| 210 } | 210 } |
| 211 if (FLAG_trace_functions) { | 211 if (FLAG_trace_functions) { |
| 212 // Preserve ECX (ic-data array or object) and EDX (arguments descriptor). | 212 // Preserve ECX (ic-data array or object) and EDX (arguments descriptor). |
| 213 __ nop(2); // Make sure the code is patchable. |
| 213 __ pushl(ECX); | 214 __ pushl(ECX); |
| 214 __ pushl(EDX); | 215 __ pushl(EDX); |
| 215 const Function& function = | 216 const Function& function = |
| 216 Function::ZoneHandle(parsed_function_.function().raw()); | 217 Function::ZoneHandle(parsed_function_.function().raw()); |
| 217 __ LoadObject(EAX, function); | 218 __ LoadObject(EAX, function); |
| 218 __ pushl(EAX); | 219 __ pushl(EAX); |
| 219 GenerateCallRuntime(AstNode::kNoId, | 220 GenerateCallRuntime(AstNode::kNoId, |
| 220 0, | 221 0, |
| 221 kTraceFunctionEntryRuntimeEntry); | 222 kTraceFunctionEntryRuntimeEntry); |
| 222 __ popl(EAX); | 223 __ popl(EAX); |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 | 265 |
| 265 // Pre entry code is called before the frame has been constructed: | 266 // Pre entry code is called before the frame has been constructed: |
| 266 // - check for stack overflow. | 267 // - check for stack overflow. |
| 267 // - optionally count function invocations. | 268 // - optionally count function invocations. |
| 268 // - optionally trigger optimizing compiler if invocation threshold has been | 269 // - optionally trigger optimizing compiler if invocation threshold has been |
| 269 // reached. | 270 // reached. |
| 270 // Note that first 5 bytes may be patched with a jump. | 271 // Note that first 5 bytes may be patched with a jump. |
| 271 // TODO(srdjan): Add check that no object is inlined in the first | 272 // TODO(srdjan): Add check that no object is inlined in the first |
| 272 // 5 bytes (length of a jump instruction). | 273 // 5 bytes (length of a jump instruction). |
| 273 void CodeGenerator::GeneratePreEntryCode() { | 274 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: | 275 // Do not optimize if: |
| 279 // - we count invocations. | 276 // - we count invocations. |
| 280 // - optimization disabled via negative 'optimization_invocation_threshold; | 277 // - optimization disabled via negative 'optimization_invocation_threshold; |
| 281 // - function is marked as non-optimizable. | 278 // - function is marked as non-optimizable. |
| 282 // - type checks are enabled. | 279 // - type checks are enabled. |
| 283 const bool may_optimize = | 280 const bool may_optimize = |
| 284 !FLAG_report_invocation_count && | 281 !FLAG_report_invocation_count && |
| 285 (FLAG_optimization_invocation_threshold >= 0) && | 282 (FLAG_optimization_invocation_threshold >= 0) && |
| 286 !Isolate::Current()->debugger()->IsActive() && | 283 !Isolate::Current()->debugger()->IsActive() && |
| 287 parsed_function_.function().is_optimizable(); | 284 parsed_function_.function().is_optimizable(); |
| 288 // Count invocation and check. | 285 // Count invocation and check. |
| 289 if (FLAG_report_invocation_count || may_optimize) { | 286 if (FLAG_report_invocation_count || may_optimize) { |
| 287 // TODO(turnidge): It would be nice to remove this nop. Right now |
| 288 // we need it to make sure the function is still patchable. |
| 289 __ nop(5); |
| 290 const Function& function = | 290 const Function& function = |
| 291 Function::ZoneHandle(parsed_function_.function().raw()); | 291 Function::ZoneHandle(parsed_function_.function().raw()); |
| 292 __ LoadObject(EAX, function); | 292 __ LoadObject(EAX, function); |
| 293 __ movl(EBX, FieldAddress(EAX, Function::invocation_counter_offset())); | 293 __ movl(EBX, FieldAddress(EAX, Function::invocation_counter_offset())); |
| 294 __ incl(EBX); | 294 __ incl(EBX); |
| 295 if (may_optimize) { | 295 if (may_optimize) { |
| 296 __ cmpl(EBX, Immediate(FLAG_optimization_invocation_threshold)); | 296 __ cmpl(EBX, Immediate(FLAG_optimization_invocation_threshold)); |
| 297 __ j(GREATER, &StubCode::OptimizeInvokedFunctionLabel()); | 297 __ j(GREATER, &StubCode::OptimizeInvokedFunctionLabel()); |
| 298 } | 298 } |
| 299 __ movl(FieldAddress(EAX, Function::invocation_counter_offset()), EBX); | 299 __ movl(FieldAddress(EAX, Function::invocation_counter_offset()), EBX); |
| (...skipping 419 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 719 // Initialize locals. | 719 // Initialize locals. |
| 720 // TODO(regis): For now, always unroll the init loop. Decide later above | 720 // TODO(regis): For now, always unroll the init loop. Decide later above |
| 721 // which threshold to implement a loop. | 721 // which threshold to implement a loop. |
| 722 // Consider emitting pushes instead of moves. | 722 // Consider emitting pushes instead of moves. |
| 723 for (int index = first_local_index; index > first_free_frame_index; index--) { | 723 for (int index = first_local_index; index > first_free_frame_index; index--) { |
| 724 if (index == first_local_index) { | 724 if (index == first_local_index) { |
| 725 __ movl(EAX, raw_null); | 725 __ movl(EAX, raw_null); |
| 726 } | 726 } |
| 727 __ movl(Address(EBP, index * kWordSize), EAX); | 727 __ movl(Address(EBP, index * kWordSize), EAX); |
| 728 } | 728 } |
| 729 |
| 730 // Generate stack overflow check. |
| 731 __ cmpl(ESP, |
| 732 Address::Absolute(Isolate::Current()->stack_limit_address())); |
| 733 Label no_stack_overflow; |
| 734 __ j(ABOVE, &no_stack_overflow); |
| 735 GenerateCallRuntime(AstNode::kNoId, |
| 736 function.token_index(), |
| 737 kStackOverflowRuntimeEntry); |
| 738 __ Bind(&no_stack_overflow); |
| 729 } | 739 } |
| 730 | 740 |
| 731 | 741 |
| 732 void CodeGenerator::GenerateReturnEpilog() { | 742 void CodeGenerator::GenerateReturnEpilog() { |
| 733 // Unchain the context(s) up to context level 0. | 743 // Unchain the context(s) up to context level 0. |
| 734 int context_level = state()->context_level(); | 744 int context_level = state()->context_level(); |
| 735 ASSERT(context_level >= 0); | 745 ASSERT(context_level >= 0); |
| 736 while (context_level-- > 0) { | 746 while (context_level-- > 0) { |
| 737 __ movl(CTX, FieldAddress(CTX, Context::parent_offset())); | 747 __ movl(CTX, FieldAddress(CTX, Context::parent_offset())); |
| 738 } | 748 } |
| (...skipping 2033 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2772 message_buffer, kMessageBufferSize, | 2782 message_buffer, kMessageBufferSize, |
| 2773 format, args); | 2783 format, args); |
| 2774 va_end(args); | 2784 va_end(args); |
| 2775 Isolate::Current()->long_jump_base()->Jump(1, message_buffer); | 2785 Isolate::Current()->long_jump_base()->Jump(1, message_buffer); |
| 2776 UNREACHABLE(); | 2786 UNREACHABLE(); |
| 2777 } | 2787 } |
| 2778 | 2788 |
| 2779 } // namespace dart | 2789 } // namespace dart |
| 2780 | 2790 |
| 2781 #endif // defined TARGET_ARCH_IA32 | 2791 #endif // defined TARGET_ARCH_IA32 |
| OLD | NEW |