Commit 50092cc3 authored by lrn@chromium.org's avatar lrn@chromium.org

Tests for RegExpMacroAssemblerIA32.

Disabled stack-limit checks.


git-svn-id: http://v8.googlecode.com/svn/branches/bleeding_edge@837 ce2b1a6d-e550-0410-aec6-3dcde31c8c00
parent f15d07af
......@@ -427,14 +427,14 @@ void Assembler::push(Label* label, RelocInfo::Mode reloc_mode) {
// If reloc_mode == NONE, the label is stored as buffer relative.
ASSERT(reloc_mode == RelocInfo::NONE);
if (label->is_bound()) {
// Index of position in Code object:
int pos = label->pos() + Code::kHeaderSize;
if (pos >= 0 && pos < 256) {
// Index of position relative to Code Object-pointer.
int rel_pos = label->pos() + Code::kHeaderSize - kHeapObjectTag;
if (rel_pos >= 0 && rel_pos < 256) {
EMIT(0x6a);
EMIT(pos);
EMIT(rel_pos);
} else {
EMIT(0x68);
emit(pos);
emit(rel_pos);
}
} else {
EMIT(0x68);
......@@ -1337,7 +1337,8 @@ void Assembler::bind_to(Label* L, int pos) {
Displacement disp = disp_at(L);
int fixup_pos = L->pos();
if (disp.type() == Displacement::CODE_RELATIVE) {
long_at_put(fixup_pos, pos + Code::kHeaderSize);
// Relative to Code* heap object pointer.
long_at_put(fixup_pos, pos + Code::kHeaderSize - kHeapObjectTag);
} else {
if (disp.type() == Displacement::UNCONDITIONAL_JUMP) {
ASSERT(byte_at(fixup_pos - 1) == 0xE9); // jmp expected
......
......@@ -2586,8 +2586,7 @@ Handle<FixedArray> RegExpEngine::Compile(RegExpParseResult* input,
// of the RegExp. We don't know the type of input string yet.
// For now, always assume two-byte strings.
RegExpMacroAssemblerIA32 macro_assembler(RegExpMacroAssemblerIA32::UC16,
(input->capture_count + 1) * 2,
ignore_case);
(input->capture_count + 1) * 2);
return compiler.Assemble(&macro_assembler,
node,
input->capture_count);
......
This diff is collapsed.
......@@ -38,7 +38,7 @@ namespace v8 { namespace internal {
class RegExpMacroAssemblerIA32: public RegExpMacroAssembler {
public:
enum Mode {ASCII = 1, UC16 = 2};
RegExpMacroAssemblerIA32(Mode mode, int registers_to_save, bool ignore_case);
RegExpMacroAssemblerIA32(Mode mode, int registers_to_save);
virtual ~RegExpMacroAssemblerIA32();
virtual void AdvanceCurrentPosition(int by);
virtual void AdvanceRegister(int reg, int by);
......@@ -100,9 +100,6 @@ class RegExpMacroAssemblerIA32: public RegExpMacroAssembler {
// The ebp-relative location of a regexp register.
Operand register_location(int register_index);
// Whether to implement case-insensitive matching.
bool ignore_case();
// Byte size of chars in the string to match (decided by the Mode argument)
size_t char_size();
......@@ -129,6 +126,10 @@ class RegExpMacroAssemblerIA32: public RegExpMacroAssembler {
// Read the current character into the destination register.
void ReadCurrentChar(Register destination);
// Adds code that checks whether preemption has been requested
// (and checks if we have hit the stack limit too).
void CheckStackLimit();
// Initial size of code buffer.
static const size_t kRegExpCodeSize = 1024;
// Initial size of constant buffers allocated during compilation.
......@@ -149,7 +150,6 @@ class RegExpMacroAssemblerIA32: public RegExpMacroAssembler {
int num_saved_registers_;
// Whether to generate code that is case-insensitive. Only relevant for
// back-references.
bool ignore_case_;
Label entry_label_;
Label start_label_;
Label success_label_;
......
......@@ -42,6 +42,14 @@
static void Test##Name()
#endif
#if (defined __arm__ || defined __thumb__ || defined ARM)
#define IA32TEST DISABLED_TEST
#define ARMTEST TEST
#else // ia32
#define IA32TEST TEST
#define ARMTEST DISABLED_TEST
#endif
class CcTest {
public:
......
......@@ -720,6 +720,239 @@ TEST(MacroAssembler) {
}
IA32TEST(MacroAssemblerIA32Success) {
typedef bool (*AsciiTest) (
SeqAsciiString** base, int start_index, int end_index, int* captures);
V8::Initialize(NULL);
// regexp-macro-assembler-ia32 needs a handle scope to allocate
// byte-arrays for constants.
v8::HandleScope scope;
RegExpMacroAssemblerIA32 m(RegExpMacroAssemblerIA32::ASCII, 4);
m.Succeed();
Handle<Object> code_object = m.GetCode();
Handle<Code> code = Handle<Code>::cast(code_object);
AsciiTest test = FUNCTION_CAST<AsciiTest>(code->entry());
int captures[4] = {42, 37, 87, 117};
Handle<String> input = Factory::NewStringFromAscii(CStrVector("foofoo"));
Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input);
Address start_adr = seq_input->GetCharsAddress();
int start_offset = start_adr - reinterpret_cast<Address>(*seq_input);
int end_offset = start_offset + seq_input->length();
bool success =
test(seq_input.location(), start_offset, end_offset, captures);
CHECK(success);
CHECK_EQ(-1, captures[0]);
CHECK_EQ(-1, captures[1]);
CHECK_EQ(-1, captures[2]);
CHECK_EQ(-1, captures[3]);
}
IA32TEST(MacroAssemblerIA32Simple) {
typedef bool (*AsciiTest) (
SeqAsciiString** base, int start_index, int end_index, int* captures);
V8::Initialize(NULL);
// regexp-macro-assembler-ia32 needs a handle scope to allocate
// byte-arrays for constants.
v8::HandleScope scope;
RegExpMacroAssemblerIA32 m(RegExpMacroAssemblerIA32::ASCII, 4);
uc16 foo_chars[3] = {'f', 'o', 'o'};
Vector<const uc16> foo(foo_chars, 3);
Label fail;
m.CheckCharacters(foo, 0, &fail);
m.WriteCurrentPositionToRegister(0);
m.AdvanceCurrentPosition(3);
m.WriteCurrentPositionToRegister(1);
m.Succeed();
m.Bind(&fail);
m.Fail();
Handle<Object> code_object = m.GetCode();
Handle<Code> code = Handle<Code>::cast(code_object);
AsciiTest test = FUNCTION_CAST<AsciiTest>(code->entry());
int captures[4] = {42, 37, 87, 117};
Handle<String> input = Factory::NewStringFromAscii(CStrVector("foofoo"));
Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input);
Address start_adr = seq_input->GetCharsAddress();
int start_offset = start_adr - reinterpret_cast<Address>(*seq_input);
int end_offset = start_offset + seq_input->length();
bool success =
test(seq_input.location(), start_offset, end_offset, captures);
CHECK(success);
CHECK_EQ(0, captures[0]);
CHECK_EQ(3, captures[1]);
CHECK_EQ(-1, captures[2]);
CHECK_EQ(-1, captures[3]);
input = Factory::NewStringFromAscii(CStrVector("barbarbar"));
seq_input = Handle<SeqAsciiString>::cast(input);
start_adr = seq_input->GetCharsAddress();
start_offset = start_adr - reinterpret_cast<Address>(*seq_input);
end_offset = start_offset + seq_input->length();
success = test(seq_input.location(), start_offset, end_offset, captures);
CHECK(!success);
}
IA32TEST(MacroAssemblerIA32Backtrack) {
typedef bool (*AsciiTest) (
SeqAsciiString** base, int start_index, int end_index, int* captures);
V8::Initialize(NULL);
// regexp-macro-assembler-ia32 needs a handle scope to allocate
// byte-arrays for constants.
v8::HandleScope scope;
RegExpMacroAssemblerIA32 m(RegExpMacroAssemblerIA32::ASCII, 0);
uc16 foo_chars[3] = {'f', 'o', 'o'};
Vector<const uc16> foo(foo_chars, 3);
Label fail;
Label backtrack;
m.LoadCurrentCharacter(10, &fail);
m.Succeed();
m.Bind(&fail);
m.PushBacktrack(&backtrack);
m.LoadCurrentCharacter(10, NULL);
m.Succeed();
m.Bind(&backtrack);
m.Fail();
Handle<Object> code_object = m.GetCode();
Handle<Code> code = Handle<Code>::cast(code_object);
AsciiTest test = FUNCTION_CAST<AsciiTest>(code->entry());
Handle<String> input = Factory::NewStringFromAscii(CStrVector("foofoo"));
Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input);
Address start_adr = seq_input->GetCharsAddress();
int start_offset = start_adr - reinterpret_cast<Address>(*seq_input);
int end_offset = start_offset + seq_input->length();
bool success =
test(seq_input.location(), start_offset, end_offset, NULL);
CHECK(!success);
}
IA32TEST(MacroAssemblerIA32Registers) {
typedef bool (*AsciiTest) (
SeqAsciiString** base, int start_index, int end_index, int* captures);
V8::Initialize(NULL);
// regexp-macro-assembler-ia32 needs a handle scope to allocate
// byte-arrays for constants.
v8::HandleScope scope;
RegExpMacroAssemblerIA32 m(RegExpMacroAssemblerIA32::ASCII, 5);
uc16 foo_chars[3] = {'f', 'o', 'o'};
Vector<const uc16> foo(foo_chars, 3);
enum registers { out1, out2, out3, out4, out5, sp, loop_cnt };
Label fail;
Label backtrack;
m.WriteCurrentPositionToRegister(out1); // Output: [0]
m.PushRegister(out1);
m.PushBacktrack(&backtrack);
m.WriteStackPointerToRegister(sp);
// Fill stack and registers
m.AdvanceCurrentPosition(2);
m.WriteCurrentPositionToRegister(out1);
m.PushRegister(out1);
m.PushBacktrack(&fail);
// Drop backtrack stack frames.
m.ReadStackPointerFromRegister(sp);
// And take the first backtrack (to &backtrack)
m.Backtrack();
m.PushCurrentPosition();
m.AdvanceCurrentPosition(2);
m.PopCurrentPosition();
m.Bind(&backtrack);
m.PopRegister(out1);
m.ReadCurrentPositionFromRegister(out1);
m.AdvanceCurrentPosition(3);
m.WriteCurrentPositionToRegister(out2); // [0,3]
Label loop;
m.SetRegister(loop_cnt, 0); // loop counter
m.Bind(&loop);
m.AdvanceRegister(loop_cnt, 1);
m.AdvanceCurrentPosition(1);
m.IfRegisterLT(loop_cnt, 3, &loop);
m.WriteCurrentPositionToRegister(out3); // [0,3,6]
Label loop2;
m.SetRegister(loop_cnt, 2); // loop counter
m.Bind(&loop2);
m.AdvanceRegister(loop_cnt, -1);
m.AdvanceCurrentPosition(1);
m.IfRegisterGE(loop_cnt, 0, &loop2);
m.WriteCurrentPositionToRegister(out4); // [0,3,6,9]
Label loop3;
Label exit_loop3;
m.ReadCurrentPositionFromRegister(out3);
m.Bind(&loop3);
m.AdvanceCurrentPosition(1);
m.CheckCurrentPosition(out4, &exit_loop3);
m.GoTo(&loop3);
m.Bind(&exit_loop3);
m.WriteCurrentPositionToRegister(out5); // [0,3,6,9,9]
m.Succeed();
m.Bind(&fail);
m.Fail();
Handle<Object> code_object = m.GetCode();
Handle<Code> code = Handle<Code>::cast(code_object);
AsciiTest test = FUNCTION_CAST<AsciiTest>(code->entry());
// String long enough for test (content doesn't matter).
Handle<String> input =
Factory::NewStringFromAscii(CStrVector("foofoofoofoofoo"));
Handle<SeqAsciiString> seq_input = Handle<SeqAsciiString>::cast(input);
Address start_adr = seq_input->GetCharsAddress();
int start_offset = start_adr - reinterpret_cast<Address>(*seq_input);
int end_offset = start_offset + seq_input->length();
int output[5];
bool success =
test(seq_input.location(), start_offset, end_offset, output);
CHECK(success);
CHECK_EQ(0, output[0]);
CHECK_EQ(3, output[1]);
CHECK_EQ(6, output[2]);
CHECK_EQ(9, output[3]);
CHECK_EQ(9, output[4]);
}
TEST(AddInverseToTable) {
static const int kLimit = 1000;
static const int kRangeCount = 16;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment