Chromium Code Reviews| Index: runtime/vm/intrinsifier_x64.cc |
| diff --git a/runtime/vm/intrinsifier_x64.cc b/runtime/vm/intrinsifier_x64.cc |
| index 1d676548d807f6af31d294c2778f7652b399e088..ca5e82571750e2aa982735d345be2d6a915d687f 100644 |
| --- a/runtime/vm/intrinsifier_x64.cc |
| +++ b/runtime/vm/intrinsifier_x64.cc |
| @@ -1510,6 +1510,99 @@ void Intrinsifier::TwoByteString_equality(Assembler* assembler) { |
| } |
| +static void GenerateRegexpSpecializationFor( |
| + Assembler* assembler, |
| + intptr_t cid, |
| + Label* entry, |
| + Label* exit, |
| + bool jump_kind = Assembler::kFarJump) { |
| + ASSERT(cid == kOneByteStringCid || cid == kExternalOneByteStringCid || |
| + cid == kTwoByteStringCid || cid == kExternalTwoByteStringCid); |
| + |
| + __ Bind(entry); |
| + |
| + // The passed string is of class cid. |
| + |
| + __ movq(RAX, FieldAddress(RBX, JSRegExp::function_offset(cid))); |
| + |
| + // Set the subject if it is currently unset. |
| + |
| + __ LoadObject(RCX, Object::null_object(), PP); |
| + __ cmpq(RCX, FieldAddress(RBX, JSRegExp::subject_offset(cid))); |
| + __ j(NOT_EQUAL, exit, jump_kind); |
| + |
| + __ StoreIntoObject(RBX, |
|
Vyacheslav Egorov (Google)
2014/10/01 20:13:21
I really don't think there is any good reason to k
|
| + FieldAddress(RBX, JSRegExp::subject_offset(cid)), |
| + RDI, |
| + false); |
| + |
| + __ jmp(exit, jump_kind); |
| +} |
| + |
| + |
| +void Intrinsifier::JSRegExp_ExecuteMatch(Assembler* assembler) { |
| + Label is_one_byte_string; |
| + Label is_two_byte_string; |
| + Label is_external_one_byte_string; |
| + Label is_external_two_byte_string; |
| + Label fallthrough; |
| + |
| + static const intptr_t kRegExpParamOffset = + 3 * kWordSize; |
| + static const intptr_t kStringParamOffset = + 2 * kWordSize; |
| + // const Smi& start_index is located at (+ 1 * kWordSize). |
| + |
| + // Register assignments are as follows: |
| + // RAX: The appropriate specialized matcher function. |
| + // RBX: The regexp object. |
| + // RCX: Temp. |
| + // RDI: Temp, Pointer to the function's code which we then tail-call. |
| + |
| + __ movq(RBX, Address(RSP, kRegExpParamOffset)); |
| + __ movq(RDI, Address(RSP, kStringParamOffset)); |
| + |
| + // Check which string class we have been passed. |
| + |
| + __ CompareClassId(RDI, kOneByteStringCid); |
| + __ j(EQUAL, &is_one_byte_string); |
| + |
| + __ CompareClassId(RDI, kTwoByteStringCid); |
| + __ j(EQUAL, &is_two_byte_string); |
| + |
| + __ CompareClassId(RDI, kExternalOneByteStringCid); |
| + __ j(EQUAL, &is_external_one_byte_string); |
| + |
| + __ CompareClassId(RDI, kExternalTwoByteStringCid); |
| + __ j(EQUAL, &is_external_two_byte_string); |
| + |
| + __ Stop("Unexpected class id"); |
| + |
| + GenerateRegexpSpecializationFor(assembler, kExternalTwoByteStringCid, |
| + &is_external_two_byte_string, &fallthrough); |
| + GenerateRegexpSpecializationFor(assembler, kExternalOneByteStringCid, |
| + &is_external_one_byte_string, &fallthrough); |
| + GenerateRegexpSpecializationFor(assembler, kTwoByteStringCid, |
| + &is_two_byte_string, &fallthrough, |
| + Assembler::kNearJump); |
| + GenerateRegexpSpecializationFor(assembler, kOneByteStringCid, |
| + &is_one_byte_string, &fallthrough, |
| + Assembler::kNearJump); |
| + |
| + // RAX contains the appropriate specialized function. |
| + |
| + __ Bind(&fallthrough); |
| + |
| + // Registers have been set up for the lazy compile stub at this point. |
| + // It expects the function in RAX, the argument descriptor in R10, and |
| + // IC-Data in RCX. Irregexp generated functions do not use either the |
| + // arguments descriptor or IC-Data, and hence these are not set here. |
| + |
| + // Tail-call the function. |
| + __ movq(RDI, FieldAddress(RAX, Function::instructions_offset())); |
| + __ addq(RDI, Immediate(Instructions::HeaderSize() - kHeapObjectTag)); |
| + __ jmp(RDI); |
| +} |
| + |
| + |
| // On stack: user tag (+1), return-address (+0). |
| void Intrinsifier::UserTag_makeCurrent(Assembler* assembler) { |
| // RBX: Isolate. |