summaryrefslogtreecommitdiffstats
path: root/runtime/reflection.cc
diff options
context:
space:
mode:
authorDave Allison <dallison@google.com>2014-08-14 00:01:12 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2014-08-12 19:23:43 +0000
commitb74ff132f217776c1ab698712bc2dbc526297288 (patch)
tree86da3e98cbd942bb4c2fda6f0f50fd44c1c0a101 /runtime/reflection.cc
parent826f1038187e00399a8c6e0044ad0ea29c0ba000 (diff)
parent648d7112609dd19c38131b3e71c37bcbbd19d11e (diff)
downloadart-b74ff132f217776c1ab698712bc2dbc526297288.zip
art-b74ff132f217776c1ab698712bc2dbc526297288.tar.gz
art-b74ff132f217776c1ab698712bc2dbc526297288.tar.bz2
Merge "Reduce stack usage for overflow checks"
Diffstat (limited to 'runtime/reflection.cc')
-rw-r--r--runtime/reflection.cc49
1 files changed, 49 insertions, 0 deletions
diff --git a/runtime/reflection.cc b/runtime/reflection.cc
index cc50961..7da450c 100644
--- a/runtime/reflection.cc
+++ b/runtime/reflection.cc
@@ -447,6 +447,14 @@ static void InvokeWithArgArray(const ScopedObjectAccessAlreadyRunnable& soa,
JValue InvokeWithVarArgs(const ScopedObjectAccessAlreadyRunnable& soa, jobject obj, jmethodID mid,
va_list args)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+ // We want to make sure that the stack is not within a small distance from the
+ // protected region in case we are calling into a leaf function whose stack
+ // check has been elided.
+ if (UNLIKELY(__builtin_frame_address(0) < soa.Self()->GetStackEnd())) {
+ ThrowStackOverflowError(soa.Self());
+ return JValue();
+ }
+
mirror::ArtMethod* method = soa.DecodeMethod(mid);
mirror::Object* receiver = method->IsStatic() ? nullptr : soa.Decode<mirror::Object*>(obj);
uint32_t shorty_len = 0;
@@ -460,6 +468,14 @@ JValue InvokeWithVarArgs(const ScopedObjectAccessAlreadyRunnable& soa, jobject o
JValue InvokeWithJValues(const ScopedObjectAccessAlreadyRunnable& soa, mirror::Object* receiver,
jmethodID mid, jvalue* args) {
+ // We want to make sure that the stack is not within a small distance from the
+ // protected region in case we are calling into a leaf function whose stack
+ // check has been elided.
+ if (UNLIKELY(__builtin_frame_address(0) < soa.Self()->GetStackEnd())) {
+ ThrowStackOverflowError(soa.Self());
+ return JValue();
+ }
+
mirror::ArtMethod* method = soa.DecodeMethod(mid);
uint32_t shorty_len = 0;
const char* shorty = method->GetShorty(&shorty_len);
@@ -472,6 +488,14 @@ JValue InvokeWithJValues(const ScopedObjectAccessAlreadyRunnable& soa, mirror::O
JValue InvokeVirtualOrInterfaceWithJValues(const ScopedObjectAccessAlreadyRunnable& soa,
mirror::Object* receiver, jmethodID mid, jvalue* args) {
+ // We want to make sure that the stack is not within a small distance from the
+ // protected region in case we are calling into a leaf function whose stack
+ // check has been elided.
+ if (UNLIKELY(__builtin_frame_address(0) < soa.Self()->GetStackEnd())) {
+ ThrowStackOverflowError(soa.Self());
+ return JValue();
+ }
+
mirror::ArtMethod* method = FindVirtualMethod(receiver, soa.DecodeMethod(mid));
uint32_t shorty_len = 0;
const char* shorty = method->GetShorty(&shorty_len);
@@ -484,6 +508,14 @@ JValue InvokeVirtualOrInterfaceWithJValues(const ScopedObjectAccessAlreadyRunnab
JValue InvokeVirtualOrInterfaceWithVarArgs(const ScopedObjectAccessAlreadyRunnable& soa,
jobject obj, jmethodID mid, va_list args) {
+ // We want to make sure that the stack is not within a small distance from the
+ // protected region in case we are calling into a leaf function whose stack
+ // check has been elided.
+ if (UNLIKELY(__builtin_frame_address(0) < soa.Self()->GetStackEnd())) {
+ ThrowStackOverflowError(soa.Self());
+ return JValue();
+ }
+
mirror::Object* receiver = soa.Decode<mirror::Object*>(obj);
mirror::ArtMethod* method = FindVirtualMethod(receiver, soa.DecodeMethod(mid));
uint32_t shorty_len = 0;
@@ -497,6 +529,14 @@ JValue InvokeVirtualOrInterfaceWithVarArgs(const ScopedObjectAccessAlreadyRunnab
void InvokeWithShadowFrame(Thread* self, ShadowFrame* shadow_frame, uint16_t arg_offset,
MethodHelper& mh, JValue* result) {
+ // We want to make sure that the stack is not within a small distance from the
+ // protected region in case we are calling into a leaf function whose stack
+ // check has been elided.
+ if (UNLIKELY(__builtin_frame_address(0) < self->GetStackEnd())) {
+ ThrowStackOverflowError(self);
+ return;
+ }
+
ArgArray arg_array(mh.GetShorty(), mh.GetShortyLength());
arg_array.BuildArgArrayFromFrame(shadow_frame, arg_offset);
shadow_frame->GetMethod()->Invoke(self, arg_array.GetArray(), arg_array.GetNumBytes(), result,
@@ -505,6 +545,15 @@ void InvokeWithShadowFrame(Thread* self, ShadowFrame* shadow_frame, uint16_t arg
jobject InvokeMethod(const ScopedObjectAccessAlreadyRunnable& soa, jobject javaMethod,
jobject javaReceiver, jobject javaArgs, bool accessible) {
+ // We want to make sure that the stack is not within a small distance from the
+ // protected region in case we are calling into a leaf function whose stack
+ // check has been elided.
+ if (UNLIKELY(__builtin_frame_address(0) <
+ soa.Self()->GetStackEndForInterpreter(true))) {
+ ThrowStackOverflowError(soa.Self());
+ return nullptr;
+ }
+
mirror::ArtMethod* m = mirror::ArtMethod::FromReflectedMethod(soa, javaMethod);
mirror::Class* declaring_class = m->GetDeclaringClass();