From 19cdd00d092067edf85e64c6567ec769843a53c2 Mon Sep 17 00:00:00 2001 From: ulan Date: Thu, 18 Jun 2015 08:45:17 -0700 Subject: [PATCH] ARM64: remove stack pushes without frame in RegExpExecStub. RegExpExecStub pushes callee-saved registers without setting up a frame. This confuses the stack iterator. Other architectures do not save these registers. BUG=chromium:487981 LOG=NO TEST=mjsunit/regress/regress-487981 Review URL: https://codereview.chromium.org/1183593005 Cr-Commit-Position: refs/heads/master@{#29120} --- src/arm64/code-stubs-arm64.cc | 32 +++++++++----------------------- test/mjsunit/regress/regress-487981.js | 22 ++++++++++++++++++++++ 2 files changed, 31 insertions(+), 23 deletions(-) create mode 100644 test/mjsunit/regress/regress-487981.js diff --git a/src/arm64/code-stubs-arm64.cc b/src/arm64/code-stubs-arm64.cc index bd70150..cfce619 100644 --- a/src/arm64/code-stubs-arm64.cc +++ b/src/arm64/code-stubs-arm64.cc @@ -2305,27 +2305,16 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { Register last_match_info_elements = x21; Register code_object = x22; - // TODO(jbramley): Is it necessary to preserve these? I don't think ARM does. - CPURegList used_callee_saved_registers(subject, - regexp_data, - last_match_info_elements, - code_object); - __ PushCPURegList(used_callee_saved_registers); - // Stack frame. - // jssp[0] : x19 - // jssp[8] : x20 - // jssp[16]: x21 - // jssp[24]: x22 - // jssp[32]: last_match_info (JSArray) - // jssp[40]: previous index - // jssp[48]: subject string - // jssp[56]: JSRegExp object - - const int kLastMatchInfoOffset = 4 * kPointerSize; - const int kPreviousIndexOffset = 5 * kPointerSize; - const int kSubjectOffset = 6 * kPointerSize; - const int kJSRegExpOffset = 7 * kPointerSize; + // jssp[00]: last_match_info (JSArray) + // jssp[08]: previous index + // jssp[16]: subject string + // jssp[24]: JSRegExp object + + const int kLastMatchInfoOffset = 0 * kPointerSize; + const int kPreviousIndexOffset = 1 * kPointerSize; + const int kSubjectOffset = 2 * kPointerSize; + const int kJSRegExpOffset = 3 * kPointerSize; // Ensure that a RegExp stack is allocated. ExternalReference address_of_regexp_stack_memory_address = @@ -2692,7 +2681,6 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { // Return last match info. __ Peek(x0, kLastMatchInfoOffset); - __ PopCPURegList(used_callee_saved_registers); // Drop the 4 arguments of the stub from the stack. __ Drop(4); __ Ret(); @@ -2715,13 +2703,11 @@ void RegExpExecStub::Generate(MacroAssembler* masm) { __ Bind(&failure); __ Mov(x0, Operand(isolate()->factory()->null_value())); - __ PopCPURegList(used_callee_saved_registers); // Drop the 4 arguments of the stub from the stack. __ Drop(4); __ Ret(); __ Bind(&runtime); - __ PopCPURegList(used_callee_saved_registers); __ TailCallRuntime(Runtime::kRegExpExec, 4, 1); // Deferred code for string handling. diff --git a/test/mjsunit/regress/regress-487981.js b/test/mjsunit/regress/regress-487981.js new file mode 100644 index 0000000..829c25c --- /dev/null +++ b/test/mjsunit/regress/regress-487981.js @@ -0,0 +1,22 @@ +// Copyright 2015 the V8 project authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +// Flags: --allow-natives-syntax --stress-compaction + +// To reliably reproduce the crash use --verify-heap --random-seed=-133185440 + +function __f_2(o) { + return o.field.b.x; +} + +try { + %OptimizeFunctionOnNextCall(__f_2); + __v_1 = __f_2(); +} catch(e) { } + +function __f_3() { __f_3(/./.test()); }; + +try { +__f_3(); +} catch(e) { } -- 2.7.4