The "enter" opcode was slow and crashes for large arguments on Windows.
git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@1066 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
This commit is contained in:
parent
7c56f0dd9a
commit
70af3cc4ba
@ -63,10 +63,10 @@ namespace v8 { namespace internal {
|
||||
* to *string_base)
|
||||
* - void** string_base (location of a handle containing the string)
|
||||
* - return address
|
||||
* ebp-> - old ebp
|
||||
* - backup of caller esi
|
||||
* - backup of caller edi
|
||||
* - backup of caller ebx
|
||||
* ebp-> - old ebp
|
||||
* - register 0 ebp[-4] (Only positions must be stored in the first
|
||||
* - register 1 ebp[-8] num_saved_registers_ registers)
|
||||
* - ...
|
||||
@ -600,6 +600,9 @@ Handle<Object> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
|
||||
|
||||
// Entry code:
|
||||
__ bind(&entry_label_);
|
||||
// Start new stack frame.
|
||||
__ push(ebp);
|
||||
__ mov(ebp, esp);
|
||||
// Save callee-save registers. Order here should correspond to order of
|
||||
// kBackup_ebx etc.
|
||||
__ push(esi);
|
||||
@ -624,8 +627,7 @@ Handle<Object> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
|
||||
__ j(above_equal, &stack_ok, taken);
|
||||
// Exit with exception.
|
||||
__ mov(eax, EXCEPTION);
|
||||
Label exit_without_leave;
|
||||
__ jmp(&exit_without_leave);
|
||||
__ jmp(&exit_label_);
|
||||
|
||||
__ bind(&stack_limit_hit);
|
||||
int num_arguments = 2;
|
||||
@ -641,12 +643,12 @@ Handle<Object> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
|
||||
__ j(equal, &retry_stack_check);
|
||||
// Return value was non-zero. Exit with exception.
|
||||
__ mov(eax, EXCEPTION);
|
||||
__ jmp(&exit_without_leave);
|
||||
__ jmp(&exit_label_);
|
||||
|
||||
__ bind(&stack_ok);
|
||||
|
||||
// Allocate space on stack for registers.
|
||||
__ enter(Immediate(num_registers_ * kPointerSize));
|
||||
__ sub(Operand(esp), Immediate(num_registers_ * kPointerSize));
|
||||
// Load string length.
|
||||
__ mov(esi, Operand(ebp, kInputEndOffset));
|
||||
// Load input position.
|
||||
@ -663,19 +665,19 @@ Handle<Object> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
|
||||
// Fill saved registers with initial value = start offset - 1
|
||||
// Fill in stack push order, to avoid accessing across an unwritten
|
||||
// page (a problem on Windows).
|
||||
const int kRegisterZeroEBPOffset = -1;
|
||||
__ mov(ecx, kRegisterZeroEBPOffset);
|
||||
// Set eax to address of char before start of input.
|
||||
__ mov(ecx, kRegisterZero);
|
||||
// Set eax to address of char before start of input
|
||||
// (effectively string position -1).
|
||||
__ lea(eax, Operand(edi, -char_size()));
|
||||
Label init_loop;
|
||||
__ bind(&init_loop);
|
||||
__ mov(Operand(ebp, ecx, times_4, +0), eax);
|
||||
__ sub(Operand(ecx), Immediate(1));
|
||||
__ cmp(ecx, -num_saved_registers_);
|
||||
__ j(greater_equal, &init_loop);
|
||||
__ mov(Operand(ebp, ecx, times_1, +0), eax);
|
||||
__ sub(Operand(ecx), Immediate(kPointerSize));
|
||||
__ cmp(ecx, kRegisterZero - num_saved_registers_ * kPointerSize);
|
||||
__ j(greater, &init_loop);
|
||||
}
|
||||
// Ensure that we have written to each stack page. Skipping a page on
|
||||
// Windows can cause segmentation faults. Assuming page size is 4k.
|
||||
// Ensure that we have written to each stack page, in order. Skipping a page
|
||||
// on Windows can cause segmentation faults. Assuming page size is 4k.
|
||||
const int kPageSize = 4096;
|
||||
const int kRegistersPerPage = kPageSize / kPointerSize;
|
||||
for (int i = num_saved_registers_ + kRegistersPerPage - 1;
|
||||
@ -700,7 +702,7 @@ Handle<Object> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
|
||||
|
||||
// Exit code:
|
||||
if (success_label_.is_linked()) {
|
||||
// Success
|
||||
// Save captures when successful.
|
||||
__ bind(&success_label_);
|
||||
if (num_saved_registers_ > 0) {
|
||||
// copy captures to output
|
||||
@ -720,11 +722,14 @@ Handle<Object> RegExpMacroAssemblerIA32::GetCode(Handle<String> source) {
|
||||
}
|
||||
// Exit and return eax
|
||||
__ bind(&exit_label_);
|
||||
__ leave();
|
||||
__ bind(&exit_without_leave); // For exiting before doing enter.
|
||||
// Skip esp past regexp registers.
|
||||
__ lea(esp, Operand(ebp, kBackup_ebx));
|
||||
// Restore callee-save registers.
|
||||
__ pop(ebx);
|
||||
__ pop(edi);
|
||||
__ pop(esi);
|
||||
// Exit function frame, restore previus one.
|
||||
__ pop(ebp);
|
||||
__ ret(0);
|
||||
|
||||
// Backtrack code (branch target for conditional backtracks).
|
||||
@ -1043,7 +1048,7 @@ Operand RegExpMacroAssemblerIA32::register_location(int register_index) {
|
||||
if (num_registers_ <= register_index) {
|
||||
num_registers_ = register_index + 1;
|
||||
}
|
||||
return Operand(ebp, -(register_index + 1) * kPointerSize);
|
||||
return Operand(ebp, kRegisterZero - register_index * kPointerSize);
|
||||
}
|
||||
|
||||
|
||||
|
@ -116,24 +116,27 @@ class RegExpMacroAssemblerIA32: public RegExpMacroAssembler {
|
||||
bool at_start);
|
||||
|
||||
private:
|
||||
// Offsets from ebp of arguments to function and stored registers.
|
||||
static const int kBackup_ebx = sizeof(uint32_t);
|
||||
static const int kBackup_edi = kBackup_ebx + sizeof(uint32_t);
|
||||
static const int kBackup_esi = kBackup_edi + sizeof(uint32_t);
|
||||
static const int kReturn_eip = kBackup_esi + sizeof(uint32_t);
|
||||
static const int kInputBuffer = kReturn_eip + sizeof(uint32_t);
|
||||
static const int kInputStartOffset = kInputBuffer + sizeof(uint32_t);
|
||||
static const int kInputEndOffset = kInputStartOffset + sizeof(uint32_t);
|
||||
static const int kRegisterOutput = kInputEndOffset + sizeof(uint32_t);
|
||||
static const int kAtStart = kRegisterOutput + sizeof(uint32_t);
|
||||
static const int kStackHighEnd = kAtStart + sizeof(uint32_t);
|
||||
// Offsets from ebp of function parameters and stored registers.
|
||||
static const int kFramePointer = 0;
|
||||
// Above the frame pointer - function parameters and return address.
|
||||
static const int kReturn_eip = kFramePointer + kPointerSize;
|
||||
static const int kInputBuffer = kReturn_eip + kPointerSize;
|
||||
static const int kInputStartOffset = kInputBuffer + kPointerSize;
|
||||
static const int kInputEndOffset = kInputStartOffset + kPointerSize;
|
||||
static const int kRegisterOutput = kInputEndOffset + kPointerSize;
|
||||
static const int kAtStart = kRegisterOutput + kPointerSize;
|
||||
static const int kStackHighEnd = kAtStart + kPointerSize;
|
||||
// Below the frame pointer - local stack variables.
|
||||
static const int kBackup_esi = kFramePointer - kPointerSize;
|
||||
static const int kBackup_edi = kBackup_esi - kPointerSize;
|
||||
static const int kBackup_ebx = kBackup_edi - kPointerSize;
|
||||
// First register address. Following registers are below it on the stack.
|
||||
static const int kRegisterZero = kBackup_ebx - kPointerSize;
|
||||
|
||||
// Initial size of code buffer.
|
||||
static const size_t kRegExpCodeSize = 1024;
|
||||
// Initial size of constant buffers allocated during compilation.
|
||||
static const int kRegExpConstantsSize = 256;
|
||||
// Only unroll loops up to this length.
|
||||
static const int kMaxInlineStringTests = 32;
|
||||
|
||||
// Compares two-byte strings case insensitively.
|
||||
// Called from generated RegExp code.
|
||||
|
Loading…
Reference in New Issue
Block a user