Commit 7d8e279a authored by bjaideep's avatar bjaideep Committed by Commit bot

PPC: [regexp] do not assume short external strings have a minimum size.

Port 3518e492

Original commit message:

    Short external strings do not cache the resource data, and may be used
    for compressible strings. The assumptions about their lengths is
    invalid and may lead to oob reads.

R=yangguo@chromium.org, joransiu@ca.ibm.com, jyan@ca.ibm.com, michael_dawson@ca.ibm.com, mbrandy@us.ibm.com

BUG=v8:4923,chromium:604897
LOG=N

Review URL: https://codereview.chromium.org/1901593005

Cr-Commit-Position: refs/heads/master@{#35671}
parent 921381bc
...@@ -1639,48 +1639,49 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { ...@@ -1639,48 +1639,49 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ LoadP(subject, MemOperand(sp, kSubjectOffset)); __ LoadP(subject, MemOperand(sp, kSubjectOffset));
__ JumpIfSmi(subject, &runtime); __ JumpIfSmi(subject, &runtime);
__ mr(r6, subject); // Make a copy of the original subject string. __ mr(r6, subject); // Make a copy of the original subject string.
__ LoadP(r3, FieldMemOperand(subject, HeapObject::kMapOffset));
__ lbz(r3, FieldMemOperand(r3, Map::kInstanceTypeOffset));
// subject: subject string // subject: subject string
// r6: subject string // r6: subject string
// r3: subject string instance type
// regexp_data: RegExp data (FixedArray) // regexp_data: RegExp data (FixedArray)
// Handle subject string according to its encoding and representation: // Handle subject string according to its encoding and representation:
// (1) Sequential string? If yes, go to (5). // (1) Sequential string? If yes, go to (4).
// (2) Anything but sequential or cons? If yes, go to (6). // (2) Sequential or cons? If not, go to (5).
// (3) Cons string. If the string is flat, replace subject with first string. // (3) Cons string. If the string is flat, replace subject with first string
// Otherwise bailout. // and go to (1). Otherwise bail out to runtime.
// (4) Is subject external? If yes, go to (7). // (4) Sequential string. Load regexp code according to encoding.
// (5) Sequential string. Load regexp code according to encoding.
// (E) Carry on. // (E) Carry on.
/// [...] /// [...]
// Deferred code at the end of the stub: // Deferred code at the end of the stub:
// (6) Not a long external string? If yes, go to (8). // (5) Long external string? If not, go to (7).
// (7) External string. Make it, offset-wise, look like a sequential string. // (6) External string. Make it, offset-wise, look like a sequential string.
// Go to (5). // Go to (4).
// (8) Short external string or not a string? If yes, bail out to runtime. // (7) Short external string or not a string? If yes, bail out to runtime.
// (9) Sliced string. Replace subject with parent. Go to (4). // (8) Sliced string. Replace subject with parent. Go to (1).
Label seq_string /* 4 */, external_string /* 6 */, check_underlying /* 1 */,
not_seq_nor_cons /* 5 */, not_long_external /* 7 */;
Label seq_string /* 5 */, external_string /* 7 */, check_underlying /* 4 */, __ bind(&check_underlying);
not_seq_nor_cons /* 6 */, not_long_external /* 8 */; __ LoadP(r3, FieldMemOperand(subject, HeapObject::kMapOffset));
__ lbz(r3, FieldMemOperand(r3, Map::kInstanceTypeOffset));
// (1) Sequential string? If yes, go to (4).
// (1) Sequential string? If yes, go to (5).
STATIC_ASSERT((kIsNotStringMask | kStringRepresentationMask | STATIC_ASSERT((kIsNotStringMask | kStringRepresentationMask |
kShortExternalStringMask) == 0x93); kShortExternalStringMask) == 0x93);
__ andi(r4, r3, Operand(kIsNotStringMask | kStringRepresentationMask | __ andi(r4, r3, Operand(kIsNotStringMask | kStringRepresentationMask |
kShortExternalStringMask)); kShortExternalStringMask));
STATIC_ASSERT((kStringTag | kSeqStringTag) == 0); STATIC_ASSERT((kStringTag | kSeqStringTag) == 0);
__ beq(&seq_string, cr0); // Go to (5). __ beq(&seq_string, cr0); // Go to (4).
// (2) Anything but sequential or cons? If yes, go to (6). // (2) Sequential or cons? If not, go to (5).
STATIC_ASSERT(kConsStringTag < kExternalStringTag); STATIC_ASSERT(kConsStringTag < kExternalStringTag);
STATIC_ASSERT(kSlicedStringTag > kExternalStringTag); STATIC_ASSERT(kSlicedStringTag > kExternalStringTag);
STATIC_ASSERT(kIsNotStringMask > kExternalStringTag); STATIC_ASSERT(kIsNotStringMask > kExternalStringTag);
STATIC_ASSERT(kShortExternalStringTag > kExternalStringTag); STATIC_ASSERT(kShortExternalStringTag > kExternalStringTag);
STATIC_ASSERT(kExternalStringTag < 0xffffu); STATIC_ASSERT(kExternalStringTag < 0xffffu);
__ cmpi(r4, Operand(kExternalStringTag)); __ cmpi(r4, Operand(kExternalStringTag));
__ bge(&not_seq_nor_cons); // Go to (6). __ bge(&not_seq_nor_cons); // Go to (5).
// (3) Cons string. Check that it's flat. // (3) Cons string. Check that it's flat.
// Replace subject with first string and reload instance type. // Replace subject with first string and reload instance type.
...@@ -1688,20 +1689,9 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { ...@@ -1688,20 +1689,9 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ CompareRoot(r3, Heap::kempty_stringRootIndex); __ CompareRoot(r3, Heap::kempty_stringRootIndex);
__ bne(&runtime); __ bne(&runtime);
__ LoadP(subject, FieldMemOperand(subject, ConsString::kFirstOffset)); __ LoadP(subject, FieldMemOperand(subject, ConsString::kFirstOffset));
__ b(&check_underlying);
// (4) Is subject external? If yes, go to (7). // (4) Sequential string. Load regexp code according to encoding.
__ bind(&check_underlying);
__ LoadP(r3, FieldMemOperand(subject, HeapObject::kMapOffset));
__ lbz(r3, FieldMemOperand(r3, Map::kInstanceTypeOffset));
STATIC_ASSERT(kSeqStringTag == 0);
STATIC_ASSERT(kStringRepresentationMask == 3);
__ andi(r0, r3, Operand(kStringRepresentationMask));
// The underlying external string is never a short external string.
STATIC_ASSERT(ExternalString::kMaxShortLength < ConsString::kMinLength);
STATIC_ASSERT(ExternalString::kMaxShortLength < SlicedString::kMinLength);
__ bne(&external_string, cr0); // Go to (7).
// (5) Sequential string. Load regexp code according to encoding.
__ bind(&seq_string); __ bind(&seq_string);
// subject: sequential subject string (or look-alike, external string) // subject: sequential subject string (or look-alike, external string)
// r6: original subject string // r6: original subject string
...@@ -1934,12 +1924,12 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { ...@@ -1934,12 +1924,12 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ TailCallRuntime(Runtime::kRegExpExec); __ TailCallRuntime(Runtime::kRegExpExec);
// Deferred code for string handling. // Deferred code for string handling.
// (6) Not a long external string? If yes, go to (8). // (5) Long external string? If not, go to (7).
__ bind(&not_seq_nor_cons); __ bind(&not_seq_nor_cons);
// Compare flags are still set. // Compare flags are still set.
__ bgt(&not_long_external); // Go to (8). __ bgt(&not_long_external); // Go to (7).
// (7) External string. Make it, offset-wise, look like a sequential string. // (6) External string. Make it, offset-wise, look like a sequential string.
__ bind(&external_string); __ bind(&external_string);
__ LoadP(r3, FieldMemOperand(subject, HeapObject::kMapOffset)); __ LoadP(r3, FieldMemOperand(subject, HeapObject::kMapOffset));
__ lbz(r3, FieldMemOperand(r3, Map::kInstanceTypeOffset)); __ lbz(r3, FieldMemOperand(r3, Map::kInstanceTypeOffset));
...@@ -1956,15 +1946,15 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { ...@@ -1956,15 +1946,15 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize); STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize);
__ subi(subject, subject, __ subi(subject, subject,
Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag)); Operand(SeqTwoByteString::kHeaderSize - kHeapObjectTag));
__ b(&seq_string); // Go to (5). __ b(&seq_string); // Go to (4).
// (8) Short external string or not a string? If yes, bail out to runtime. // (7) Short external string or not a string? If yes, bail out to runtime.
__ bind(&not_long_external); __ bind(&not_long_external);
STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag != 0); STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag != 0);
__ andi(r0, r4, Operand(kIsNotStringMask | kShortExternalStringMask)); __ andi(r0, r4, Operand(kIsNotStringMask | kShortExternalStringMask));
__ bne(&runtime, cr0); __ bne(&runtime, cr0);
// (9) Sliced string. Replace subject with parent. Go to (4). // (8) Sliced string. Replace subject with parent. Go to (4).
// Load offset into r11 and replace subject string with parent. // Load offset into r11 and replace subject string with parent.
__ LoadP(r11, FieldMemOperand(subject, SlicedString::kOffsetOffset)); __ LoadP(r11, FieldMemOperand(subject, SlicedString::kOffsetOffset));
__ SmiUntag(r11); __ SmiUntag(r11);
......
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