OLD | NEW |
1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 2009 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 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
50 * LoadCurrentCharacter before using any of the dispatch methods. | 50 * LoadCurrentCharacter before using any of the dispatch methods. |
51 * - r8 : points to tip of backtrack stack | 51 * - r8 : points to tip of backtrack stack |
52 * - r9 : Unused, might be used by C code and expected unchanged. | 52 * - r9 : Unused, might be used by C code and expected unchanged. |
53 * - r10 : End of input (points to byte after last character in input). | 53 * - r10 : End of input (points to byte after last character in input). |
54 * - r11 : Frame pointer. Used to access arguments, local variables and | 54 * - r11 : Frame pointer. Used to access arguments, local variables and |
55 * RegExp registers. | 55 * RegExp registers. |
56 * - r12 : IP register, used by assembler. Very volatile. | 56 * - r12 : IP register, used by assembler. Very volatile. |
57 * - r13/sp : points to tip of C stack. | 57 * - r13/sp : points to tip of C stack. |
58 * | 58 * |
59 * The remaining registers are free for computations. | 59 * The remaining registers are free for computations. |
| 60 * Each call to a public method should retain this convention. |
60 * | 61 * |
61 * Each call to a public method should retain this convention. | |
62 * The stack will have the following structure: | 62 * The stack will have the following structure: |
63 * - direct_call (if 1, direct call from JavaScript code, if 0 call | 63 * - fp[48] direct_call (if 1, direct call from JavaScript code, |
64 * through the runtime system) | 64 * if 0, call through the runtime system). |
65 * - stack_area_base (High end of the memory area to use as | 65 * - fp[44] stack_area_base (High end of the memory area to use as |
66 * backtracking stack) | 66 * backtracking stack). |
67 * - int* capture_array (int[num_saved_registers_], for output). | 67 * - fp[40] int* capture_array (int[num_saved_registers_], for output). |
68 * --- sp when called --- | 68 * - fp[36] secondary link/return address used by native call. |
69 * - link address | 69 * --- sp when called --- |
70 * - backup of registers r4..r11 | 70 * - fp[32] return address (lr). |
71 * - end of input (Address of end of string) | 71 * - fp[28] old frame pointer (r11). |
72 * - start of input (Address of first character in string) | 72 * - fp[0..24] backup of registers r4..r10. |
73 * - start index (character index of start) | 73 * --- frame pointer ---- |
74 * --- frame pointer ---- | 74 * - fp[-4] end of input (Address of end of string). |
75 * - void* input_string (location of a handle containing the string) | 75 * - fp[-8] start of input (Address of first character in string). |
76 * - Offset of location before start of input (effectively character | 76 * - fp[-12] start index (character index of start). |
77 * position -1). Used to initialize capture registers to a non-position. | 77 * - fp[-16] void* input_string (location of a handle containing the string). |
78 * - At start (if 1, we are starting at the start of the | 78 * - fp[-20] Offset of location before start of input (effectively character |
79 * string, otherwise 0) | 79 * position -1). Used to initialize capture registers to a |
80 * - register 0 (Only positions must be stored in the first | 80 * non-position. |
81 * - register 1 num_saved_registers_ registers) | 81 * - fp[-24] At start (if 1, we are starting at the start of the |
82 * - ... | 82 * string, otherwise 0) |
83 * - register num_registers-1 | 83 * - fp[-28] register 0 (Only positions must be stored in the first |
84 * --- sp --- | 84 * - register 1 num_saved_registers_ registers) |
| 85 * - ... |
| 86 * - register num_registers-1 |
| 87 * --- sp --- |
85 * | 88 * |
86 * The first num_saved_registers_ registers are initialized to point to | 89 * The first num_saved_registers_ registers are initialized to point to |
87 * "character -1" in the string (i.e., char_size() bytes before the first | 90 * "character -1" in the string (i.e., char_size() bytes before the first |
88 * character of the string). The remaining registers start out as garbage. | 91 * character of the string). The remaining registers start out as garbage. |
89 * | 92 * |
90 * The data up to the return address must be placed there by the calling | 93 * The data up to the return address must be placed there by the calling |
91 * code, by calling the code entry as cast to a function with the signature: | 94 * code and the remaining arguments are passed in registers, e.g. by calling the |
| 95 * code entry as cast to a function with the signature: |
92 * int (*match)(String* input_string, | 96 * int (*match)(String* input_string, |
93 * int start_index, | 97 * int start_index, |
94 * Address start, | 98 * Address start, |
95 * Address end, | 99 * Address end, |
| 100 * Address secondary_return_address, // Only used by native call. |
96 * int* capture_output_array, | 101 * int* capture_output_array, |
97 * bool at_start, | |
98 * byte* stack_area_base, | 102 * byte* stack_area_base, |
99 * bool direct_call) | 103 * bool direct_call = false) |
100 * The call is performed by NativeRegExpMacroAssembler::Execute() | 104 * The call is performed by NativeRegExpMacroAssembler::Execute() |
101 * (in regexp-macro-assembler.cc). | 105 * (in regexp-macro-assembler.cc) via the CALL_GENERATED_REGEXP_CODE macro |
| 106 * in arm/simulator-arm.h. |
| 107 * When calling as a non-direct call (i.e., from C++ code), the return address |
| 108 * area is overwritten with the LR register by the RegExp code. When doing a |
| 109 * direct call from generated code, the return address is placed there by |
| 110 * the calling code, as in a normal exit frame. |
102 */ | 111 */ |
103 | 112 |
104 #define __ ACCESS_MASM(masm_) | 113 #define __ ACCESS_MASM(masm_) |
105 | 114 |
106 RegExpMacroAssemblerARM::RegExpMacroAssemblerARM( | 115 RegExpMacroAssemblerARM::RegExpMacroAssemblerARM( |
107 Mode mode, | 116 Mode mode, |
108 int registers_to_save) | 117 int registers_to_save) |
109 : masm_(new MacroAssembler(NULL, kRegExpCodeSize)), | 118 : masm_(new MacroAssembler(NULL, kRegExpCodeSize)), |
110 mode_(mode), | 119 mode_(mode), |
111 num_registers_(registers_to_save), | 120 num_registers_(registers_to_save), |
(...skipping 479 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
591 __ jmp(&exit_label_); | 600 __ jmp(&exit_label_); |
592 } | 601 } |
593 | 602 |
594 | 603 |
595 Handle<Object> RegExpMacroAssemblerARM::GetCode(Handle<String> source) { | 604 Handle<Object> RegExpMacroAssemblerARM::GetCode(Handle<String> source) { |
596 // Finalize code - write the entry point code now we know how many | 605 // Finalize code - write the entry point code now we know how many |
597 // registers we need. | 606 // registers we need. |
598 | 607 |
599 // Entry code: | 608 // Entry code: |
600 __ bind(&entry_label_); | 609 __ bind(&entry_label_); |
601 // Push Link register. | |
602 // Push arguments | 610 // Push arguments |
603 // Save callee-save registers. | 611 // Save callee-save registers. |
604 // Start new stack frame. | 612 // Start new stack frame. |
| 613 // Store link register in existing stack-cell. |
605 // Order here should correspond to order of offset constants in header file. | 614 // Order here should correspond to order of offset constants in header file. |
606 RegList registers_to_retain = r4.bit() | r5.bit() | r6.bit() | | 615 RegList registers_to_retain = r4.bit() | r5.bit() | r6.bit() | |
607 r7.bit() | r8.bit() | r9.bit() | r10.bit() | fp.bit(); | 616 r7.bit() | r8.bit() | r9.bit() | r10.bit() | fp.bit(); |
608 RegList argument_registers = r0.bit() | r1.bit() | r2.bit() | r3.bit(); | 617 RegList argument_registers = r0.bit() | r1.bit() | r2.bit() | r3.bit(); |
609 __ stm(db_w, sp, argument_registers | registers_to_retain | lr.bit()); | 618 __ stm(db_w, sp, argument_registers | registers_to_retain | lr.bit()); |
610 // Set frame pointer just above the arguments. | 619 // Set frame pointer in space for it if this is not a direct call |
| 620 // from generated code. |
611 __ add(frame_pointer(), sp, Operand(4 * kPointerSize)); | 621 __ add(frame_pointer(), sp, Operand(4 * kPointerSize)); |
612 __ push(r0); // Make room for "position - 1" constant (value is irrelevant). | 622 __ push(r0); // Make room for "position - 1" constant (value is irrelevant). |
613 __ push(r0); // Make room for "at start" constant (value is irrelevant). | 623 __ push(r0); // Make room for "at start" constant (value is irrelevant). |
614 // Check if we have space on the stack for registers. | 624 // Check if we have space on the stack for registers. |
615 Label stack_limit_hit; | 625 Label stack_limit_hit; |
616 Label stack_ok; | 626 Label stack_ok; |
617 | 627 |
618 ExternalReference stack_limit = | 628 ExternalReference stack_limit = |
619 ExternalReference::address_of_stack_limit(); | 629 ExternalReference::address_of_stack_limit(); |
620 __ mov(r0, Operand(stack_limit)); | 630 __ mov(r0, Operand(stack_limit)); |
(...skipping 136 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
757 | 767 |
758 // String might have moved: Reload end of string from frame. | 768 // String might have moved: Reload end of string from frame. |
759 __ ldr(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); | 769 __ ldr(end_of_input_address(), MemOperand(frame_pointer(), kInputEnd)); |
760 SafeReturn(); | 770 SafeReturn(); |
761 } | 771 } |
762 | 772 |
763 // Backtrack stack overflow code. | 773 // Backtrack stack overflow code. |
764 if (stack_overflow_label_.is_linked()) { | 774 if (stack_overflow_label_.is_linked()) { |
765 SafeCallTarget(&stack_overflow_label_); | 775 SafeCallTarget(&stack_overflow_label_); |
766 // Reached if the backtrack-stack limit has been hit. | 776 // Reached if the backtrack-stack limit has been hit. |
767 | |
768 Label grow_failed; | 777 Label grow_failed; |
769 | 778 |
770 // Call GrowStack(backtrack_stackpointer()) | 779 // Call GrowStack(backtrack_stackpointer(), &stack_base) |
771 static const int num_arguments = 2; | 780 static const int num_arguments = 2; |
772 __ PrepareCallCFunction(num_arguments, r0); | 781 __ PrepareCallCFunction(num_arguments, r0); |
773 __ mov(r0, backtrack_stackpointer()); | 782 __ mov(r0, backtrack_stackpointer()); |
774 __ add(r1, frame_pointer(), Operand(kStackHighEnd)); | 783 __ add(r1, frame_pointer(), Operand(kStackHighEnd)); |
775 ExternalReference grow_stack = | 784 ExternalReference grow_stack = |
776 ExternalReference::re_grow_stack(); | 785 ExternalReference::re_grow_stack(); |
777 __ CallCFunction(grow_stack, num_arguments); | 786 __ CallCFunction(grow_stack, num_arguments); |
778 // If return NULL, we have failed to grow the stack, and | 787 // If return NULL, we have failed to grow the stack, and |
779 // must exit with a stack-overflow exception. | 788 // must exit with a stack-overflow exception. |
780 __ cmp(r0, Operand(0, RelocInfo::NONE)); | 789 __ cmp(r0, Operand(0, RelocInfo::NONE)); |
(...skipping 481 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1262 __ ldr(pc, MemOperand(sp, stack_alignment, PostIndex)); | 1271 __ ldr(pc, MemOperand(sp, stack_alignment, PostIndex)); |
1263 } | 1272 } |
1264 | 1273 |
1265 #undef __ | 1274 #undef __ |
1266 | 1275 |
1267 #endif // V8_INTERPRETED_REGEXP | 1276 #endif // V8_INTERPRETED_REGEXP |
1268 | 1277 |
1269 }} // namespace v8::internal | 1278 }} // namespace v8::internal |
1270 | 1279 |
1271 #endif // V8_TARGET_ARCH_ARM | 1280 #endif // V8_TARGET_ARCH_ARM |
OLD | NEW |