Commit 14c9cbd4 authored by jyan's avatar jyan Committed by Commit bot

S390: [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, bjaideep@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/1911633002

Cr-Commit-Position: refs/heads/master@{#35682}
parent 644bade7
......@@ -1631,49 +1631,50 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ LoadP(subject, MemOperand(sp, kSubjectOffset));
__ JumpIfSmi(subject, &runtime);
__ LoadRR(r5, subject); // Make a copy of the original subject string.
__ LoadP(r2, FieldMemOperand(subject, HeapObject::kMapOffset));
__ LoadlB(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset));
// subject: subject string
// r5: subject string
// r2: subject string instance type
// regexp_data: RegExp data (FixedArray)
// Handle subject string according to its encoding and representation:
// (1) Sequential string? If yes, go to (5).
// (2) Anything but sequential or cons? If yes, go to (6).
// (3) Cons string. If the string is flat, replace subject with first string.
// Otherwise bailout.
// (4) Is subject external? If yes, go to (7).
// (5) Sequential string. Load regexp code according to encoding.
// (1) Sequential string? If yes, go to (4).
// (2) Sequential or cons? If not, go to (5).
// (3) Cons string. If the string is flat, replace subject with first string
// and go to (1). Otherwise bail out to runtime.
// (4) Sequential string. Load regexp code according to encoding.
// (E) Carry on.
/// [...]
// Deferred code at the end of the stub:
// (6) Not a long external string? If yes, go to (8).
// (7) External string. Make it, offset-wise, look like a sequential string.
// Go to (5).
// (8) Short external string or not a string? If yes, bail out to runtime.
// (9) Sliced string. Replace subject with parent. Go to (4).
// (5) Long external string? If not, go to (7).
// (6) External string. Make it, offset-wise, look like a sequential string.
// Go to (4).
// (7) Short external string or not a string? If yes, bail out to runtime.
// (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 */,
not_seq_nor_cons /* 6 */, not_long_external /* 8 */;
__ bind(&check_underlying);
__ LoadP(r2, FieldMemOperand(subject, HeapObject::kMapOffset));
__ LoadlB(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset));
// (1) Sequential string? If yes, go to (4).
// (1) Sequential string? If yes, go to (5).
STATIC_ASSERT((kIsNotStringMask | kStringRepresentationMask |
kShortExternalStringMask) == 0x93);
__ mov(r3, Operand(kIsNotStringMask | kStringRepresentationMask |
kShortExternalStringMask));
__ AndP(r3, r2);
STATIC_ASSERT((kStringTag | kSeqStringTag) == 0);
__ beq(&seq_string); // Go to (5).
__ beq(&seq_string, Label::kNear); // 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(kSlicedStringTag > kExternalStringTag);
STATIC_ASSERT(kIsNotStringMask > kExternalStringTag);
STATIC_ASSERT(kShortExternalStringTag > kExternalStringTag);
STATIC_ASSERT(kExternalStringTag < 0xffffu);
__ CmpP(r3, 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.
// Replace subject with first string and reload instance type.
......@@ -1681,20 +1682,9 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ CompareRoot(r2, Heap::kempty_stringRootIndex);
__ bne(&runtime);
__ LoadP(subject, FieldMemOperand(subject, ConsString::kFirstOffset));
__ b(&check_underlying);
// (4) Is subject external? If yes, go to (7).
__ bind(&check_underlying);
__ LoadP(r2, FieldMemOperand(subject, HeapObject::kMapOffset));
__ LoadlB(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset));
STATIC_ASSERT(kSeqStringTag == 0);
STATIC_ASSERT(kStringRepresentationMask == 3);
__ tmll(r2, 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); // Go to (7).
// (5) Sequential string. Load regexp code according to encoding.
// (4) Sequential string. Load regexp code according to encoding.
__ bind(&seq_string);
// subject: sequential subject string (or look-alike, external string)
// r5: original subject string
......@@ -1937,12 +1927,12 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
__ TailCallRuntime(Runtime::kRegExpExec);
// 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);
// Compare flags are still set.
__ bgt(&not_long_external); // Go to (8).
__ bgt(&not_long_external, Label::kNear); // 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);
__ LoadP(r2, FieldMemOperand(subject, HeapObject::kMapOffset));
__ LoadlB(r2, FieldMemOperand(r2, Map::kInstanceTypeOffset));
......@@ -1959,16 +1949,16 @@ void RegExpExecStub::Generate(MacroAssembler* masm) {
STATIC_ASSERT(SeqTwoByteString::kHeaderSize == SeqOneByteString::kHeaderSize);
__ SubP(subject, subject,
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);
STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag != 0);
__ mov(r0, Operand(kIsNotStringMask | kShortExternalStringMask));
__ AndP(r0, r3);
__ bne(&runtime);
// (9) Sliced string. Replace subject with parent. Go to (4).
// (8) Sliced string. Replace subject with parent. Go to (4).
// Load offset into ip and replace subject string with parent.
__ LoadP(ip, FieldMemOperand(subject, SlicedString::kOffsetOffset));
__ SmiUntag(ip);
......
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