blob: 51bb68f24aed6e1325685c520f411960e971f620 [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
2 * Copyright (C) 2011 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Shih-wei Liao9407c602011-09-16 10:36:43 -070016
Nicolas Geoffraye982f0b2014-08-13 02:11:24 +010017#include "check_reference_map_visitor.h"
Shih-wei Liao9407c602011-09-16 10:36:43 -070018#include "jni.h"
19
20namespace art {
21
Nicolas Geoffraye982f0b2014-08-13 02:11:24 +010022#define CHECK_REGS(...) do { \
23 int t[] = {__VA_ARGS__}; \
24 int t_size = sizeof(t) / sizeof(*t); \
25 CheckReferences(t, t_size, GetNativePcOffset()); \
26} while (false);
Shih-wei Liao9407c602011-09-16 10:36:43 -070027
28static int gJava_StackWalk_refmap_calls = 0;
29
Nicolas Geoffraye982f0b2014-08-13 02:11:24 +010030class TestReferenceMapVisitor : public CheckReferenceMapVisitor {
31 public:
Mathieu Chartier90443472015-07-16 20:32:27 -070032 explicit TestReferenceMapVisitor(Thread* thread) SHARED_REQUIRES(Locks::mutator_lock_)
Nicolas Geoffraye982f0b2014-08-13 02:11:24 +010033 : CheckReferenceMapVisitor(thread) {}
Shih-wei Liao9407c602011-09-16 10:36:43 -070034
Mathieu Chartier90443472015-07-16 20:32:27 -070035 bool VisitFrame() SHARED_REQUIRES(Locks::mutator_lock_) {
Nicolas Geoffraye982f0b2014-08-13 02:11:24 +010036 if (CheckReferenceMapVisitor::VisitFrame()) {
Elliott Hughes530fa002012-03-12 11:44:49 -070037 return true;
Shih-wei Liao9407c602011-09-16 10:36:43 -070038 }
Mathieu Chartiere401d142015-04-22 13:56:20 -070039 ArtMethod* m = GetMethod();
Mathieu Chartierbfd9a432014-05-21 17:43:44 -070040 StringPiece m_name(m->GetName());
Shih-wei Liao9407c602011-09-16 10:36:43 -070041
42 // Given the method name and the number of times the method has been called,
43 // we know the Dex registers with live reference values. Assert that what we
44 // find is what is expected.
Sebastien Hertzc94ff122016-02-29 16:54:16 +010045 if (m_name == "$noinline$f") {
Shih-wei Liao9407c602011-09-16 10:36:43 -070046 if (gJava_StackWalk_refmap_calls == 1) {
Ian Rogers0399dde2012-06-06 17:09:28 -070047 CHECK_EQ(1U, GetDexPc());
Sebastien Hertzc94ff122016-02-29 16:54:16 +010048 CHECK_REGS(1); // v1: this
Shih-wei Liao9407c602011-09-16 10:36:43 -070049 } else {
Elliott Hughesf5a7a472011-10-07 14:31:02 -070050 CHECK_EQ(gJava_StackWalk_refmap_calls, 2);
Ian Rogers0399dde2012-06-06 17:09:28 -070051 CHECK_EQ(5U, GetDexPc());
Sebastien Hertzc94ff122016-02-29 16:54:16 +010052 CHECK_REGS(1); // v1: this
Shih-wei Liao9407c602011-09-16 10:36:43 -070053 }
Ian Rogers6d4d9fc2011-11-30 16:24:48 -080054 } else if (m_name == "g") {
Shih-wei Liao9407c602011-09-16 10:36:43 -070055 if (gJava_StackWalk_refmap_calls == 1) {
Sebastien Hertzc94ff122016-02-29 16:54:16 +010056 CHECK_EQ(0xdU, GetDexPc());
57 CHECK_REGS(0, 2); // v2: this (Note that v1 is not in the minimal root set)
Shih-wei Liao9407c602011-09-16 10:36:43 -070058 } else {
Elliott Hughesf5a7a472011-10-07 14:31:02 -070059 CHECK_EQ(gJava_StackWalk_refmap_calls, 2);
Sebastien Hertzc94ff122016-02-29 16:54:16 +010060 CHECK_EQ(0xdU, GetDexPc());
Shih-wei Liao0839bdb2011-10-12 10:50:44 -070061 CHECK_REGS(0, 2);
Shih-wei Liao9407c602011-09-16 10:36:43 -070062 }
Ian Rogers6d4d9fc2011-11-30 16:24:48 -080063 } else if (m_name == "shlemiel") {
Shih-wei Liao9407c602011-09-16 10:36:43 -070064 if (gJava_StackWalk_refmap_calls == 1) {
Sebastien Hertzc94ff122016-02-29 16:54:16 +010065 CHECK_EQ(0x393U, GetDexPc());
Shih-wei Liao0839bdb2011-10-12 10:50:44 -070066 CHECK_REGS(2, 4, 5, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 21, 25);
Shih-wei Liao9407c602011-09-16 10:36:43 -070067 } else {
Elliott Hughesf5a7a472011-10-07 14:31:02 -070068 CHECK_EQ(gJava_StackWalk_refmap_calls, 2);
Sebastien Hertzc94ff122016-02-29 16:54:16 +010069 CHECK_EQ(0x393U, GetDexPc());
Shih-wei Liao0839bdb2011-10-12 10:50:44 -070070 CHECK_REGS(2, 4, 5, 7, 8, 9, 10, 11, 13, 14, 15, 16, 17, 18, 19, 21, 25);
Shih-wei Liao9407c602011-09-16 10:36:43 -070071 }
72 }
Elliott Hughes530fa002012-03-12 11:44:49 -070073
74 return true;
Shih-wei Liao9407c602011-09-16 10:36:43 -070075 }
76};
77
Andreas Gampe1c83cbc2014-07-22 18:52:29 -070078extern "C" JNIEXPORT jint JNICALL Java_Main_stackmap(JNIEnv*, jobject, jint count) {
Ian Rogers7a22fa62013-01-23 12:16:16 -080079 ScopedObjectAccess soa(Thread::Current());
Shih-wei Liao0839bdb2011-10-12 10:50:44 -070080 CHECK_EQ(count, 0);
Shih-wei Liao9407c602011-09-16 10:36:43 -070081 gJava_StackWalk_refmap_calls++;
82
83 // Visitor
Ian Rogers7a22fa62013-01-23 12:16:16 -080084 TestReferenceMapVisitor mapper(soa.Self());
Ian Rogers0399dde2012-06-06 17:09:28 -070085 mapper.WalkStack();
Shih-wei Liao9407c602011-09-16 10:36:43 -070086
87 return count + 1;
88}
89
Andreas Gampe1c83cbc2014-07-22 18:52:29 -070090extern "C" JNIEXPORT jint JNICALL Java_Main_refmap2(JNIEnv*, jobject, jint count) {
Ian Rogers7a22fa62013-01-23 12:16:16 -080091 ScopedObjectAccess soa(Thread::Current());
Shih-wei Liao9407c602011-09-16 10:36:43 -070092 gJava_StackWalk_refmap_calls++;
93
94 // Visitor
Ian Rogers7a22fa62013-01-23 12:16:16 -080095 TestReferenceMapVisitor mapper(soa.Self());
Ian Rogers0399dde2012-06-06 17:09:28 -070096 mapper.WalkStack();
Shih-wei Liao9407c602011-09-16 10:36:43 -070097
98 return count + 1;
99}
100
Brian Carlstrom7934ac22013-07-26 10:54:15 -0700101} // namespace art