From b4697727e946e8d96d5345a4db7ff72842d60466 Mon Sep 17 00:00:00 2001 From: yangguo Date: Wed, 20 Apr 2016 22:58:08 -0700 Subject: [PATCH] MIPS64: [regexp] do not assume short external strings have a minimum size. Port 3518e492c0939759ae1a2623bbd606646ee172f1 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=bmeurer@chromium.org BUG=v8:4923,chromium:604897 LOG=N Review URL: https://codereview.chromium.org/1902393004 Cr-Commit-Position: refs/heads/master@{#35683} --- src/mips64/code-stubs-mips64.cc | 72 ++++++++++++++++----------------- test/cctest/cctest.status | 3 -- 2 files changed, 35 insertions(+), 40 deletions(-) diff --git a/src/mips64/code-stubs-mips64.cc b/src/mips64/code-stubs-mips64.cc index 575e755601..a459e78ee9 100644 --- a/src/mips64/code-stubs-mips64.cc +++ b/src/mips64/code-stubs-mips64.cc @@ -1685,48 +1685,53 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { __ mov(a3, subject); // Make a copy of the original subject string. __ ld(a0, FieldMemOperand(subject, HeapObject::kMapOffset)); __ lbu(a0, FieldMemOperand(a0, Map::kInstanceTypeOffset)); + // subject: subject string - // a3: subject string // a0: subject string instance type + // a3: subject string // 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 check_underlying; // (4) - Label seq_string; // (5) - Label not_seq_nor_cons; // (6) - Label external_string; // (7) - Label not_long_external; // (8) + Label check_underlying; // (1) + Label seq_string; // (4) + Label not_seq_nor_cons; // (5) + Label external_string; // (6) + Label not_long_external; // (7) - // (1) Sequential string? If yes, go to (5). + __ bind(&check_underlying); + __ ld(a2, FieldMemOperand(subject, HeapObject::kMapOffset)); + __ Daddu(a0, a2, Map::kInstanceTypeOffset); + __ lbu(a0, MemOperand(a0)); + + // (1) Sequential string? If yes, go to (4). __ And(a1, a0, Operand(kIsNotStringMask | kStringRepresentationMask | kShortExternalStringMask)); STATIC_ASSERT((kStringTag | kSeqStringTag) == 0); - __ Branch(&seq_string, eq, a1, Operand(zero_reg)); // Go to (5). + __ Branch(&seq_string, eq, a1, Operand(zero_reg)); // 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); - // Go to (6). + // Go to (5). __ Branch(¬_seq_nor_cons, ge, a1, Operand(kExternalStringTag)); // (3) Cons string. Check that it's flat. @@ -1735,16 +1740,9 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { __ LoadRoot(a1, Heap::kempty_stringRootIndex); __ Branch(&runtime, ne, a0, Operand(a1)); __ ld(subject, FieldMemOperand(subject, ConsString::kFirstOffset)); + __ jmp(&check_underlying); - // (4) Is subject external? If yes, go to (7). - __ bind(&check_underlying); - __ ld(a0, FieldMemOperand(subject, HeapObject::kMapOffset)); - __ lbu(a0, FieldMemOperand(a0, Map::kInstanceTypeOffset)); - STATIC_ASSERT(kSeqStringTag == 0); - __ And(at, a0, Operand(kStringRepresentationMask)); - __ Branch(&external_string, ne, at, Operand(zero_reg)); // 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) // a3: original subject string @@ -1987,12 +1985,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(¬_seq_nor_cons); - // Go to (8). + // Go to (7). __ Branch(¬_long_external, gt, a1, Operand(kExternalStringTag)); - // (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); __ ld(a0, FieldMemOperand(subject, HeapObject::kMapOffset)); __ lbu(a0, FieldMemOperand(a0, Map::kInstanceTypeOffset)); @@ -2012,20 +2010,20 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { __ Dsubu(subject, subject, SeqTwoByteString::kHeaderSize - kHeapObjectTag); - __ jmp(&seq_string); // Go to (5). + __ jmp(&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(¬_long_external); STATIC_ASSERT(kNotStringTag != 0 && kShortExternalStringTag !=0); __ And(at, a1, Operand(kIsNotStringMask | kShortExternalStringMask)); __ Branch(&runtime, ne, at, Operand(zero_reg)); - // (9) Sliced string. Replace subject with parent. Go to (4). + // (8) Sliced string. Replace subject with parent. Go to (4). // Load offset into t0 and replace subject string with parent. __ ld(t0, FieldMemOperand(subject, SlicedString::kOffsetOffset)); __ SmiUntag(t0); __ ld(subject, FieldMemOperand(subject, SlicedString::kParentOffset)); - __ jmp(&check_underlying); // Go to (4). + __ jmp(&check_underlying); // Go to (1). #endif // V8_INTERPRETED_REGEXP } diff --git a/test/cctest/cctest.status b/test/cctest/cctest.status index d75e52f803..c1b28d35f1 100644 --- a/test/cctest/cctest.status +++ b/test/cctest/cctest.status @@ -86,9 +86,6 @@ 'test-func-name-inference/UpperCaseClass': [FAIL], 'test-func-name-inference/LowerCaseClass': [FAIL], - # BUG(4923). MIPS64 port is missing. - 'test-regexp/UncachedExternalString': [PASS, ['arch==mips64 or arch==mips64el', FAIL]], - ############################################################################## # TurboFan compiler failures.