Revision: 3947
Author: [email protected]
Date: Thu Feb 25 04:18:55 2010
Log: AllignFrame/CallCFuntion moved from regexp-macro-assembler-ia32 to
macro-assembler-ia32 (like in x64 version).
Review URL: http://codereview.chromium.org/657080
http://code.google.com/p/v8/source/detail?r=3947
Modified:
/branches/bleeding_edge/src/ia32/codegen-ia32.cc
/branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc
/branches/bleeding_edge/src/ia32/macro-assembler-ia32.h
/branches/bleeding_edge/src/ia32/regexp-macro-assembler-ia32.cc
/branches/bleeding_edge/src/ia32/regexp-macro-assembler-ia32.h
/branches/bleeding_edge/src/x64/codegen-x64.cc
=======================================
--- /branches/bleeding_edge/src/ia32/codegen-ia32.cc Wed Feb 24 00:33:51
2010
+++ /branches/bleeding_edge/src/ia32/codegen-ia32.cc Thu Feb 25 04:18:55
2010
@@ -5743,21 +5743,12 @@
ASSERT(args->length() == 0);
frame_->SpillAll();
- // Make sure the frame is aligned like the OS expects.
- static const int kFrameAlignment = OS::ActivationFrameAlignment();
- if (kFrameAlignment > 0) {
- ASSERT(IsPowerOf2(kFrameAlignment));
- __ mov(edi, Operand(esp)); // Save in callee-saved register.
- __ and_(esp, -kFrameAlignment);
- }
+ int num_arguments = 0;
+ __ PrepareCallCFunction(num_arguments, eax);
// Call V8::RandomPositiveSmi().
- __ call(FUNCTION_ADDR(V8::RandomPositiveSmi), RelocInfo::RUNTIME_ENTRY);
-
- // Restore stack pointer from callee-saved register edi.
- if (kFrameAlignment > 0) {
- __ mov(esp, Operand(edi));
- }
+ __ CallCFunction(ExternalReference::random_positive_smi_function(),
+ num_arguments);
Result result = allocator_->Allocate(eax);
frame_->Push(&result);
@@ -9207,48 +9198,50 @@
// All checks done. Now push arguments for native regexp code.
__ IncrementCounter(&Counters::regexp_entry_native, 1);
+ static const int kRegExpExecuteArguments = 7;
+ __ PrepareCallCFunction(kRegExpExecuteArguments, ecx);
+
// Argument 7: Indicate that this is a direct call from JavaScript.
- __ push(Immediate(1));
+ __ mov(Operand(esp, 6 * kPointerSize), Immediate(1));
// Argument 6: Start (high end) of backtracking stack memory area.
__ mov(ecx,
Operand::StaticVariable(address_of_regexp_stack_memory_address));
__ add(ecx,
Operand::StaticVariable(address_of_regexp_stack_memory_size));
- __ push(ecx);
+ __ mov(Operand(esp, 5 * kPointerSize), ecx);
// Argument 5: static offsets vector buffer.
- __
push(Immediate(ExternalReference::address_of_static_offsets_vector()));
+ __ mov(Operand(esp, 4 * kPointerSize),
+ Immediate(ExternalReference::address_of_static_offsets_vector()));
// Argument 4: End of string data
// Argument 3: Start of string data
- Label push_two_byte, push_rest;
+ Label setup_two_byte, setup_rest;
__ test(edi, Operand(edi));
__ mov(edi, FieldOperand(eax, String::kLengthOffset));
- __ j(zero, &push_two_byte);
+ __ j(zero, &setup_two_byte);
__ lea(ecx, FieldOperand(eax, edi, times_1,
SeqAsciiString::kHeaderSize));
- __ push(ecx); // Argument 4.
+ __ mov(Operand(esp, 3 * kPointerSize), ecx); // Argument 4.
__ lea(ecx, FieldOperand(eax, ebx, times_1,
SeqAsciiString::kHeaderSize));
- __ push(ecx); // Argument 3.
- __ jmp(&push_rest);
-
- __ bind(&push_two_byte);
+ __ mov(Operand(esp, 2 * kPointerSize), ecx); // Argument 3.
+ __ jmp(&setup_rest);
+
+ __ bind(&setup_two_byte);
__ lea(ecx, FieldOperand(eax, edi, times_2,
SeqTwoByteString::kHeaderSize));
- __ push(ecx); // Argument 4.
+ __ mov(Operand(esp, 3 * kPointerSize), ecx); // Argument 4.
__ lea(ecx, FieldOperand(eax, ebx, times_2,
SeqTwoByteString::kHeaderSize));
- __ push(ecx); // Argument 3.
-
- __ bind(&push_rest);
+ __ mov(Operand(esp, 2 * kPointerSize), ecx); // Argument 3.
+
+ __ bind(&setup_rest);
// Argument 2: Previous index.
- __ push(ebx);
+ __ mov(Operand(esp, 1 * kPointerSize), ebx);
// Argument 1: Subject string.
- __ push(eax);
+ __ mov(Operand(esp, 0 * kPointerSize), eax);
// Locate the code entry and call it.
__ add(Operand(edx), Immediate(Code::kHeaderSize - kHeapObjectTag));
- __ call(Operand(edx));
- // Remove arguments.
- __ add(Operand(esp), Immediate(7 * kPointerSize));
+ __ CallCFunction(edx, kRegExpExecuteArguments);
// Check the result.
Label success;
=======================================
--- /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc Wed Feb 24
00:33:51 2010
+++ /branches/bleeding_edge/src/ia32/macro-assembler-ia32.cc Thu Feb 25
04:18:55 2010
@@ -1620,6 +1620,41 @@
cmp(scratch1, kFlatAsciiStringTag | (kFlatAsciiStringTag << 3));
j(not_equal, failure);
}
+
+
+void MacroAssembler::PrepareCallCFunction(int num_arguments, Register
scratch) {
+ int frameAlignment = OS::ActivationFrameAlignment();
+ if (frameAlignment != 0) {
+ // Make stack end at alignment and make room for num_arguments words
+ // and the original value of esp.
+ mov(scratch, esp);
+ sub(Operand(esp), Immediate((num_arguments + 1) * kPointerSize));
+ ASSERT(IsPowerOf2(frameAlignment));
+ and_(esp, -frameAlignment);
+ mov(Operand(esp, num_arguments * kPointerSize), scratch);
+ } else {
+ sub(Operand(esp), Immediate(num_arguments * kPointerSize));
+ }
+}
+
+
+void MacroAssembler::CallCFunction(ExternalReference function,
+ int num_arguments) {
+ // Trashing eax is ok as it will be the return value.
+ mov(Operand(eax), Immediate(function));
+ CallCFunction(eax, num_arguments);
+}
+
+
+void MacroAssembler::CallCFunction(Register function,
+ int num_arguments) {
+ call(Operand(function));
+ if (OS::ActivationFrameAlignment() != 0) {
+ mov(esp, Operand(esp, num_arguments * kPointerSize));
+ } else {
+ add(Operand(esp), Immediate(num_arguments * sizeof(int32_t)));
+ }
+}
CodePatcher::CodePatcher(byte* address, int size)
=======================================
--- /branches/bleeding_edge/src/ia32/macro-assembler-ia32.h Wed Feb 24
00:33:51 2010
+++ /branches/bleeding_edge/src/ia32/macro-assembler-ia32.h Thu Feb 25
04:18:55 2010
@@ -377,6 +377,23 @@
int num_arguments,
int result_size);
+ // Before calling a C-function from generated code, align arguments on
stack.
+ // After aligning the frame, arguments must be stored in esp[0], esp[4],
+ // etc., not pushed. The argument count assumes all arguments are word
sized.
+ // Some compilers/platforms require the stack to be aligned when calling
+ // C++ code.
+ // Needs a scratch register to do some arithmetic. This register will be
+ // trashed.
+ void PrepareCallCFunction(int num_arguments, Register scratch);
+
+ // Calls a C function and cleans up the space for arguments allocated
+ // by PrepareCallCFunction. The called function is not allowed to
trigger a
+ // garbage collection, since that might move the code and invalidate the
+ // return address (unless this is somehow accounted for by the called
+ // function).
+ void CallCFunction(ExternalReference function, int num_arguments);
+ void CallCFunction(Register function, int num_arguments);
+
void PushHandleScope(Register scratch);
// Pops a handle scope using the specified scratch register and
=======================================
--- /branches/bleeding_edge/src/ia32/regexp-macro-assembler-ia32.cc Tue Jan
26 03:08:42 2010
+++ /branches/bleeding_edge/src/ia32/regexp-macro-assembler-ia32.cc Thu Feb
25 04:18:55 2010
@@ -325,7 +325,7 @@
__ push(ebx);
const int argument_count = 3;
- FrameAlign(argument_count, ecx);
+ __ PrepareCallCFunction(argument_count, ecx);
// Put arguments into allocated stack area, last argument highest on
stack.
// Parameters are
// Address byte_offset1 - Address captured substring's start.
@@ -346,7 +346,7 @@
ExternalReference compare =
ExternalReference::re_case_insensitive_compare_uc16();
- CallCFunction(compare, argument_count);
+ __ CallCFunction(compare, argument_count);
// Pop original values before reacting on result value.
__ pop(ebx);
__ pop(backtrack_stackpointer());
@@ -785,12 +785,12 @@
// Call GrowStack(backtrack_stackpointer())
int num_arguments = 2;
- FrameAlign(num_arguments, ebx);
+ __ PrepareCallCFunction(num_arguments, ebx);
__ lea(eax, Operand(ebp, kStackHighEnd));
__ mov(Operand(esp, 1 * kPointerSize), eax);
__ mov(Operand(esp, 0 * kPointerSize), backtrack_stackpointer());
ExternalReference grow_stack = ExternalReference::re_grow_stack();
- CallCFunction(grow_stack, num_arguments);
+ __ CallCFunction(grow_stack, num_arguments);
// If return NULL, we have failed to grow the stack, and
// must exit with a stack-overflow exception.
__ or_(eax, Operand(eax));
@@ -952,7 +952,7 @@
void RegExpMacroAssemblerIA32::CallCheckStackGuardState(Register scratch) {
int num_arguments = 3;
- FrameAlign(num_arguments, scratch);
+ __ PrepareCallCFunction(num_arguments, scratch);
// RegExp code frame pointer.
__ mov(Operand(esp, 2 * kPointerSize), ebp);
// Code* of self.
@@ -962,7 +962,7 @@
__ mov(Operand(esp, 0 * kPointerSize), eax);
ExternalReference check_stack_guard =
ExternalReference::re_check_stack_guard_state();
- CallCFunction(check_stack_guard, num_arguments);
+ __ CallCFunction(check_stack_guard, num_arguments);
}
@@ -1151,37 +1151,6 @@
__ bind(&no_stack_overflow);
}
-
-
-void RegExpMacroAssemblerIA32::FrameAlign(int num_arguments, Register
scratch) {
- // TODO(lrn): Since we no longer use the system stack arbitrarily (but
we do
- // use it, e.g., for SafeCall), we know the number of elements on the
stack
- // since the last frame alignment. We might be able to do this simpler
then.
- int frameAlignment = OS::ActivationFrameAlignment();
- if (frameAlignment != 0) {
- // Make stack end at alignment and make room for num_arguments words
- // and the original value of esp.
- __ mov(scratch, esp);
- __ sub(Operand(esp), Immediate((num_arguments + 1) * kPointerSize));
- ASSERT(IsPowerOf2(frameAlignment));
- __ and_(esp, -frameAlignment);
- __ mov(Operand(esp, num_arguments * kPointerSize), scratch);
- } else {
- __ sub(Operand(esp), Immediate(num_arguments * kPointerSize));
- }
-}
-
-
-void RegExpMacroAssemblerIA32::CallCFunction(ExternalReference function,
- int num_arguments) {
- __ mov(Operand(eax), Immediate(function));
- __ call(Operand(eax));
- if (OS::ActivationFrameAlignment() != 0) {
- __ mov(esp, Operand(esp, num_arguments * kPointerSize));
- } else {
- __ add(Operand(esp), Immediate(num_arguments * sizeof(int32_t)));
- }
-}
void RegExpMacroAssemblerIA32::LoadCurrentCharacterUnchecked(int cp_offset,
=======================================
--- /branches/bleeding_edge/src/ia32/regexp-macro-assembler-ia32.h Tue Jan
26 03:08:42 2010
+++ /branches/bleeding_edge/src/ia32/regexp-macro-assembler-ia32.h Thu Feb
25 04:18:55 2010
@@ -187,21 +187,6 @@
// (ecx) and increments it by a word size.
inline void Pop(Register target);
- // Before calling a C-function from generated code, align arguments on
stack.
- // After aligning the frame, arguments must be stored in esp[0], esp[4],
- // etc., not pushed. The argument count assumes all arguments are word
sized.
- // Some compilers/platforms require the stack to be aligned when calling
- // C++ code.
- // Needs a scratch register to do some arithmetic. This register will be
- // trashed.
- inline void FrameAlign(int num_arguments, Register scratch);
-
- // Calls a C function and cleans up the space for arguments allocated
- // by FrameAlign. The called function is not allowed to trigger a garbage
- // collection, since that might move the code and invalidate the return
- // address (unless this is somehow accounted for).
- inline void CallCFunction(ExternalReference function, int num_arguments);
-
MacroAssembler* masm_;
// Which mode to generate code for (ASCII or UC16).
=======================================
--- /branches/bleeding_edge/src/x64/codegen-x64.cc Wed Feb 24 00:33:51 2010
+++ /branches/bleeding_edge/src/x64/codegen-x64.cc Thu Feb 25 04:18:55 2010
@@ -3958,21 +3958,12 @@
frame_->SpillAll();
__ push(rsi);
- // Make sure the frame is aligned like the OS expects.
- static const int kFrameAlignment = OS::ActivationFrameAlignment();
- if (kFrameAlignment > 0) {
- ASSERT(IsPowerOf2(kFrameAlignment));
- __ movq(rbx, rsp); // Save in AMD-64 abi callee-saved register.
- __ and_(rsp, Immediate(-kFrameAlignment));
- }
+ int num_arguments = 0;
+ __ PrepareCallCFunction(num_arguments);
// Call V8::RandomPositiveSmi().
- __ Call(FUNCTION_ADDR(V8::RandomPositiveSmi), RelocInfo::RUNTIME_ENTRY);
-
- // Restore stack pointer from callee-saved register.
- if (kFrameAlignment > 0) {
- __ movq(rsp, rbx);
- }
+ __ CallCFunction(ExternalReference::random_positive_smi_function(),
+ num_arguments);
__ pop(rsi);
Result result = allocator_->Allocate(rax);
--
v8-dev mailing list
[email protected]
http://groups.google.com/group/v8-dev