Move Method shorty to managed heap
Change-Id: Iafd05502b498c823063d0603915a92db8c95f060
diff --git a/src/check_jni.cc b/src/check_jni.cc
index 0486284..38f47dc 100644
--- a/src/check_jni.cc
+++ b/src/check_jni.cc
@@ -446,7 +446,7 @@
void checkSig(jmethodID mid, const char* expectedType, bool isStatic) {
ScopedJniThreadState ts(mEnv);
const Method* m = DecodeMethod(ts, mid);
- if (*expectedType != m->GetShorty()[0]) {
+ if (*expectedType != m->GetShorty()->CharAt(0)) {
LOG(ERROR) << "JNI ERROR: expected return type '" << *expectedType << "' calling " << PrettyMethod(m);
JniAbort();
} else if (isStatic && !m->IsStatic()) {
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 6d5c643..c81df8d 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -886,7 +886,7 @@
dst->SetProtoIdx(method_id.proto_idx_);
dst->SetCodeItemOffset(src.code_off_);
const char* shorty = dex_file.GetShorty(method_id.proto_idx_);
- dst->SetShorty(shorty);
+ dst->SetShorty(String::AllocFromModifiedUtf8(shorty));
dst->SetAccessFlags(src.access_flags_);
dst->SetReturnTypeIdx(dex_file.GetProtoId(method_id.proto_idx_).return_type_idx_);
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc
index cb1cd8d..c3bb4c3 100644
--- a/src/class_linker_test.cc
+++ b/src/class_linker_test.cc
@@ -512,6 +512,7 @@
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, dex_cache_strings_), "shadow$_dex_cache_strings_"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, invoke_stub_array_), "shadow$_invoke_stub_array_"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, mapping_table_), "shadow$_mapping_table_"));
+ offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, shorty_), "shadow$_shorty_"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, signature_), "shadow$_signature_"));
// alphabetical 32-bit
@@ -531,7 +532,6 @@
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, num_registers_), "shadow$_num_registers_"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, proto_idx_), "shadow$_proto_idx_"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, return_pc_offset_in_bytes_), "shadow$_return_pc_offset_in_bytes_"));
- offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, shorty_), "shadow$_shorty_"));
offsets.push_back(CheckOffset(OFFSETOF_MEMBER(Method, java_slot_), "slot"));
};
};
diff --git a/src/compiler/Ralloc.cc b/src/compiler/Ralloc.cc
index 8bbf659..aaec17b 100644
--- a/src/compiler/Ralloc.cc
+++ b/src/compiler/Ralloc.cc
@@ -106,9 +106,9 @@
// Skip past "this"
sReg++;
}
- const art::StringPiece& shorty = cUnit->method->GetShorty();
- for (int i = 1; i < shorty.size(); i++) {
- char arg = shorty[i];
+ String* shorty = cUnit->method->GetShorty();
+ for (int i = 1; i < shorty->GetLength(); i++) {
+ char arg = shorty->CharAt(i);
// Is it wide?
if ((arg == 'D') || (arg == 'J')) {
cUnit->regLocation[sReg].wide = true;
diff --git a/src/jni_internal.cc b/src/jni_internal.cc
index 2ea6f76..c60dc24 100644
--- a/src/jni_internal.cc
+++ b/src/jni_internal.cc
@@ -123,9 +123,9 @@
byte* CreateArgArray(ScopedJniThreadState& ts, Method* method, va_list ap) {
size_t num_bytes = method->NumArgArrayBytes();
UniquePtr<byte[]> arg_array(new byte[num_bytes]);
- const StringPiece& shorty = method->GetShorty();
- for (int i = 1, offset = 0; i < shorty.size(); ++i) {
- switch (shorty[i]) {
+ String* shorty = method->GetShorty();
+ for (int i = 1, offset = 0; i < shorty->GetLength(); ++i) {
+ switch (shorty->CharAt(i)) {
case 'Z':
case 'B':
case 'C':
@@ -160,9 +160,9 @@
byte* CreateArgArray(ScopedJniThreadState& ts, Method* method, jvalue* args) {
size_t num_bytes = method->NumArgArrayBytes();
UniquePtr<byte[]> arg_array(new byte[num_bytes]);
- const StringPiece& shorty = method->GetShorty();
- for (int i = 1, offset = 0; i < shorty.size(); ++i) {
- switch (shorty[i]) {
+ String* shorty = method->GetShorty();
+ for (int i = 1, offset = 0; i < shorty->GetLength(); ++i) {
+ switch (shorty->CharAt(i)) {
case 'Z':
case 'B':
case 'C':
diff --git a/src/jni_internal_arm.cc b/src/jni_internal_arm.cc
index ed42c12..65dc380 100644
--- a/src/jni_internal_arm.cc
+++ b/src/jni_internal_arm.cc
@@ -101,7 +101,7 @@
__ blx(IP);
// If the method returns a value, store it to the result pointer.
- char ch = method->GetShorty()[0];
+ char ch = method->GetShorty()->CharAt(0);
if (ch != 'V') {
// Load the result JValue pointer of the stub caller's out args.
__ LoadFromOffset(kLoadWord, IP, SP, frame_size);
diff --git a/src/jni_internal_x86.cc b/src/jni_internal_x86.cc
index a6917d4..a096da0 100644
--- a/src/jni_internal_x86.cc
+++ b/src/jni_internal_x86.cc
@@ -57,7 +57,7 @@
// pop arguments and padding up to saved EDI
__ addl(ESP, Immediate(frame_size + pad_size - kPointerSize));
- char ch = method->GetShorty()[0];
+ char ch = method->GetShorty()->CharAt(0);
if (ch != 'V') {
// Load the result JValue pointer.
__ movl(EDI, Address(ESP, 24));
diff --git a/src/object.cc b/src/object.cc
index c66791b..6cb6d98 100644
--- a/src/object.cc
+++ b/src/object.cc
@@ -359,10 +359,10 @@
}
size_t Method::NumArgArrayBytes() const {
- const StringPiece& shorty = GetShorty();
+ String* shorty = GetShorty();
size_t num_bytes = 0;
- for (int i = 1; i < shorty.length(); ++i) {
- char ch = shorty[i];
+ for (int i = 1; i < shorty->GetLength(); ++i) {
+ char ch = shorty->CharAt(i);
if (ch == 'D' || ch == 'J') {
num_bytes += 8;
} else if (ch == 'L') {
@@ -376,13 +376,20 @@
return num_bytes;
}
+size_t Method::NumArgs() const {
+ // "1 +" because the first in Args is the receiver.
+ // "- 1" because we don't count the return type.
+ return (IsStatic() ? 0 : 1) + GetShorty()->GetLength() - 1;
+}
+
// The number of reference arguments to this method including implicit this
// pointer
size_t Method::NumReferenceArgs() const {
- const StringPiece& shorty = GetShorty();
+ String* shorty = GetShorty();
size_t result = IsStatic() ? 0 : 1; // The implicit this pointer.
- for (int i = 1; i < shorty.length(); i++) {
- if ((shorty[i] == 'L') || (shorty[i] == '[')) {
+ for (int i = 1; i < shorty->GetLength(); i++) {
+ char ch = shorty->CharAt(i);
+ if ((ch == 'L') || (ch == '[')) {
result++;
}
}
@@ -391,10 +398,11 @@
// The number of long or double arguments
size_t Method::NumLongOrDoubleArgs() const {
- const StringPiece& shorty = GetShorty();
+ String* shorty = GetShorty();
size_t result = 0;
- for (int i = 1; i < shorty.length(); i++) {
- if ((shorty[i] == 'D') || (shorty[i] == 'J')) {
+ for (int i = 1; i < shorty->GetLength(); i++) {
+ char ch = shorty->CharAt(i);
+ if ((ch == 'D') || (ch == 'J')) {
result++;
}
}
@@ -409,7 +417,7 @@
} else if (param == 0) {
return true; // this argument
}
- return GetShorty()[param] == 'L';
+ return GetShorty()->CharAt(param) == 'L';
}
// Is the given method parameter a long or double?
@@ -420,7 +428,8 @@
} else if (param == 0) {
return false; // this argument
}
- return (GetShorty()[param] == 'J') || (GetShorty()[param] == 'D');
+ char ch = GetShorty()->CharAt(param);
+ return (ch == 'J' || ch == 'D');
}
static size_t ShortyCharToSize(char x) {
@@ -441,11 +450,11 @@
} else if (param == 0) {
return kPointerSize; // this argument
}
- return ShortyCharToSize(GetShorty()[param]);
+ return ShortyCharToSize(GetShorty()->CharAt(param));
}
size_t Method::ReturnSize() const {
- return ShortyCharToSize(GetShorty()[0]);
+ return ShortyCharToSize(GetShorty()->CharAt(0));
}
bool Method::HasSameNameAndDescriptor(const Method* that) const {
diff --git a/src/object.h b/src/object.h
index bc9ec7e..01ed500 100644
--- a/src/object.h
+++ b/src/object.h
@@ -643,14 +643,9 @@
void SetName(String* new_name);
- const char* GetShorty() const;
+ String* GetShorty() const;
- void SetShorty(const char* new_shorty) {
- DCHECK(NULL == GetFieldPtr<const char*>(
- OFFSET_OF_OBJECT_MEMBER(Method, shorty_), false));
- DCHECK_LE(1u, strlen(new_shorty));
- SetFieldPtr(OFFSET_OF_OBJECT_MEMBER(Method, shorty_), new_shorty, false);
- }
+ void SetShorty(String* new_shorty);
const String* GetSignature() const;
@@ -838,11 +833,7 @@
// need to deal with it.
//
// The number of Args that should be supplied to this method
- size_t NumArgs() const {
- // "1 +" because the first in Args is the receiver.
- // "- 1" because we don't count the return type.
- return (IsStatic() ? 0 : 1) + strlen(GetShorty()) - 1;
- }
+ size_t NumArgs() const;
// The number of reference arguments to this method including implicit this
// pointer.
@@ -1039,6 +1030,9 @@
// Storage for mapping_table_
const ByteArray* mapping_table_;
+ // The short-form method descriptor string.
+ String* shorty_;
+
// The method descriptor. This represents the parameters a method
// takes and value it returns. This string is a list of the type
// descriptors for the parameters enclosed in parenthesis followed
@@ -1102,9 +1096,6 @@
// Offset of return PC within frame for compiled code (in bytes)
size_t return_pc_offset_in_bytes_;
- // The short-form method descriptor string. TODO: make String*
- const char* shorty_;
-
uint32_t java_slot_;
static Class* java_lang_reflect_Method_;
@@ -2594,12 +2585,19 @@
}
-inline const char* Method::GetShorty() const {
+inline String* Method::GetShorty() const {
DCHECK(GetDeclaringClass()->IsLoaded());
- return GetFieldPtr<const char*>(
+ return GetFieldObject<String*>(
OFFSET_OF_OBJECT_MEMBER(Method, shorty_), false);
}
+inline void Method::SetShorty(String* new_shorty) {
+ DCHECK(NULL == GetFieldObject<String*>(
+ OFFSET_OF_OBJECT_MEMBER(Method, shorty_), false));
+ DCHECK_LE(1, new_shorty->GetLength());
+ SetFieldObject(OFFSET_OF_OBJECT_MEMBER(Method, shorty_), new_shorty, false);
+}
+
inline const String* Method::GetSignature() const {
DCHECK(GetDeclaringClass()->IsLoaded());
const String* result =