summaryrefslogtreecommitdiffstats
path: root/compiler/dex/quick/mips/call_mips.cc
diff options
context:
space:
mode:
authorDouglas Leung <douglas.leung@imgtec.com>2015-07-02 16:42:08 -0700
committerRoland Levillain <rpl@google.com>2015-07-03 17:29:27 +0100
commitccbbda2b716bcc0dd9ad7b6c7bf9079efa3fca23 (patch)
tree52b01bc48dadce390c2e4ceffacdc16f674d3dd0 /compiler/dex/quick/mips/call_mips.cc
parent3abd437507f8ba30a238a52c273c9944dcb9d5a1 (diff)
downloadandroid_art-ccbbda2b716bcc0dd9ad7b6c7bf9079efa3fca23.tar.gz
android_art-ccbbda2b716bcc0dd9ad7b6c7bf9079efa3fca23.tar.bz2
android_art-ccbbda2b716bcc0dd9ad7b6c7bf9079efa3fca23.zip
Add implicit null pointer and stack overflow checks for Mips.
(cherry picked from commit 22bb5a2ebc1e2724179faf4660b2735dcb185f21) Bug: 21555893 Change-Id: I2a995be128a5603d08753c14956dd8c8240ac63c
Diffstat (limited to 'compiler/dex/quick/mips/call_mips.cc')
-rw-r--r--compiler/dex/quick/mips/call_mips.cc26
1 files changed, 21 insertions, 5 deletions
diff --git a/compiler/dex/quick/mips/call_mips.cc b/compiler/dex/quick/mips/call_mips.cc
index da12d8e3bf..853980d10a 100644
--- a/compiler/dex/quick/mips/call_mips.cc
+++ b/compiler/dex/quick/mips/call_mips.cc
@@ -24,6 +24,7 @@
#include "dex/quick/dex_file_to_method_inliner_map.h"
#include "dex/quick/mir_to_lir-inl.h"
#include "driver/compiler_driver.h"
+#include "driver/compiler_options.h"
#include "entrypoints/quick/quick_entrypoints.h"
#include "gc/accounting/card_table.h"
#include "mips_lir.h"
@@ -285,12 +286,25 @@ void MipsMir2Lir::GenEntrySequence(RegLocation* ArgLocs, RegLocation rl_method)
RegStorage check_reg = AllocPtrSizeTemp();
RegStorage new_sp = AllocPtrSizeTemp();
const RegStorage rs_sp = TargetPtrReg(kSp);
+ const size_t kStackOverflowReservedUsableBytes = GetStackOverflowReservedBytes(target);
+ const bool large_frame = static_cast<size_t>(frame_size_) > kStackOverflowReservedUsableBytes;
+ bool generate_explicit_stack_overflow_check = large_frame ||
+ !cu_->compiler_driver->GetCompilerOptions().GetImplicitStackOverflowChecks();
+
if (!skip_overflow_check) {
- // Load stack limit.
- if (cu_->target64) {
- LoadWordDisp(TargetPtrReg(kSelf), Thread::StackEndOffset<8>().Int32Value(), check_reg);
+ if (generate_explicit_stack_overflow_check) {
+ // Load stack limit.
+ if (cu_->target64) {
+ LoadWordDisp(TargetPtrReg(kSelf), Thread::StackEndOffset<8>().Int32Value(), check_reg);
+ } else {
+ Load32Disp(TargetPtrReg(kSelf), Thread::StackEndOffset<4>().Int32Value(), check_reg);
+ }
} else {
- Load32Disp(TargetPtrReg(kSelf), Thread::StackEndOffset<4>().Int32Value(), check_reg);
+ // Implicit stack overflow check.
+ // Generate a load from [sp, #-overflowsize]. If this is in the stack
+ // redzone we will get a segmentation fault.
+ Load32Disp(rs_sp, -kStackOverflowReservedUsableBytes, rs_rZERO);
+ MarkPossibleStackOverflowException();
}
}
// Spill core callee saves.
@@ -298,7 +312,7 @@ void MipsMir2Lir::GenEntrySequence(RegLocation* ArgLocs, RegLocation rl_method)
// NOTE: promotion of FP regs currently unsupported, thus no FP spill.
DCHECK_EQ(num_fp_spills_, 0);
const int frame_sub = frame_size_ - spill_count * ptr_size;
- if (!skip_overflow_check) {
+ if (!skip_overflow_check && generate_explicit_stack_overflow_check) {
class StackOverflowSlowPath : public LIRSlowPath {
public:
StackOverflowSlowPath(Mir2Lir* m2l, LIR* branch, size_t sp_displace)
@@ -329,6 +343,8 @@ void MipsMir2Lir::GenEntrySequence(RegLocation* ArgLocs, RegLocation rl_method)
OpRegCopy(rs_sp, new_sp); // Establish stack.
cfi_.AdjustCFAOffset(frame_sub);
} else {
+ // Here if skip_overflow_check or doing implicit stack overflow check.
+ // Just make room on the stack for the frame now.
OpRegImm(kOpSub, rs_sp, frame_sub);
cfi_.AdjustCFAOffset(frame_sub);
}