Clarify CodeAndMethods to CodeAndDirectMethods
Change-Id: Ifa564ea25f4c7eb168f367274679a4915b9f4715
diff --git a/src/class_linker.cc b/src/class_linker.cc
index 4738926..41a1c55 100644
--- a/src/class_linker.cc
+++ b/src/class_linker.cc
@@ -434,12 +434,12 @@
AllocObjectArray<Class>(dex_file.NumTypeIds()),
AllocObjectArray<Method>(dex_file.NumMethodIds()),
AllocObjectArray<Field>(dex_file.NumFieldIds()),
- AllocCodeAndMethods(dex_file.NumMethodIds()));
+ AllocCodeAndDirectMethods(dex_file.NumMethodIds()));
return dex_cache;
}
-CodeAndMethods* ClassLinker::AllocCodeAndMethods(size_t length) {
- return down_cast<CodeAndMethods*>(IntArray::Alloc(CodeAndMethods::LengthAsArray(length)));
+CodeAndDirectMethods* ClassLinker::AllocCodeAndDirectMethods(size_t length) {
+ return down_cast<CodeAndDirectMethods*>(IntArray::Alloc(CodeAndDirectMethods::LengthAsArray(length)));
}
Class* ClassLinker::AllocClass(Class* java_lang_Class, size_t class_size) {
@@ -698,7 +698,7 @@
dex_file.dexReadClassDataMethod(&class_data, &dex_method, &last_idx);
Method* meth = AllocMethod();
klass->SetDirectMethod(i, meth);
- LoadMethod(dex_file, dex_method, klass, meth);
+ LoadMethod(dex_file, dex_method, klass, meth, true);
// TODO: register maps
}
}
@@ -714,7 +714,7 @@
dex_file.dexReadClassDataMethod(&class_data, &dex_method, &last_idx);
Method* meth = AllocMethod();
klass->SetVirtualMethod(i, meth);
- LoadMethod(dex_file, dex_method, klass, meth);
+ LoadMethod(dex_file, dex_method, klass, meth, false);
// TODO: register maps
}
}
@@ -751,7 +751,8 @@
void ClassLinker::LoadMethod(const DexFile& dex_file,
const DexFile::Method& src,
Class* klass,
- Method* dst) {
+ Method* dst,
+ bool is_direct) {
const DexFile::MethodId& method_id = dex_file.GetMethodId(src.method_idx_);
dst->declaring_class_ = klass;
dst->name_ = ResolveString(dex_file, method_id.name_idx_, klass->GetDexCache());
@@ -769,7 +770,9 @@
dst->dex_cache_types_ = klass->dex_cache_->GetTypes();
dst->dex_cache_methods_ = klass->dex_cache_->GetMethods();
dst->dex_cache_fields_ = klass->dex_cache_->GetFields();
- dst->dex_cache_code_and_methods_ = klass->dex_cache_->GetCodeAndMethods();
+ dst->dex_cache_code_and_direct_methods_ = klass->dex_cache_->GetCodeAndDirectMethods();
+
+ dst->is_direct_ = is_direct;
// TODO: check for finalize method
diff --git a/src/class_linker.h b/src/class_linker.h
index 306613f..5e3ac78 100644
--- a/src/class_linker.h
+++ b/src/class_linker.h
@@ -146,7 +146,7 @@
ObjectArray<T>* AllocObjectArray(size_t length) {
return ObjectArray<T>::Alloc(GetClassRoot(kObjectArrayClass), length);
}
- CodeAndMethods* AllocCodeAndMethods(size_t length);
+ CodeAndDirectMethods* AllocCodeAndDirectMethods(size_t length);
Class* CreatePrimitiveClass(const char* descriptor);
@@ -176,7 +176,8 @@
void LoadMethod(const DexFile& dex_file,
const DexFile::Method& dex_method,
Class* klass,
- Method* dst);
+ Method* dst,
+ bool is_direct);
Class* LookupClass(const StringPiece& descriptor, const ClassLoader* class_loader);
diff --git a/src/class_linker_test.cc b/src/class_linker_test.cc
index 71bf523..9fd5fb5 100644
--- a/src/class_linker_test.cc
+++ b/src/class_linker_test.cc
@@ -105,13 +105,13 @@
EXPECT_TRUE(method->dex_cache_types_ != NULL);
EXPECT_TRUE(method->dex_cache_methods_ != NULL);
EXPECT_TRUE(method->dex_cache_fields_ != NULL);
- EXPECT_TRUE(method->dex_cache_code_and_methods_ != NULL);
+ EXPECT_TRUE(method->dex_cache_code_and_direct_methods_ != NULL);
EXPECT_EQ(method->declaring_class_->dex_cache_->GetStrings(), method->dex_cache_strings_);
EXPECT_EQ(method->declaring_class_->dex_cache_->GetTypes(), method->dex_cache_types_);
EXPECT_EQ(method->declaring_class_->dex_cache_->GetMethods(), method->dex_cache_methods_);
EXPECT_EQ(method->declaring_class_->dex_cache_->GetFields(), method->dex_cache_fields_);
- EXPECT_EQ(method->declaring_class_->dex_cache_->GetCodeAndMethods(),
- method->dex_cache_code_and_methods_);
+ EXPECT_EQ(method->declaring_class_->dex_cache_->GetCodeAndDirectMethods(),
+ method->dex_cache_code_and_direct_methods_);
}
void AssertField(Class* klass, Field* field) {
@@ -143,6 +143,7 @@
EXPECT_TRUE(klass->IsAbstract());
if (klass->NumDirectMethods() == 1) {
EXPECT_TRUE(klass->GetDirectMethod(0)->GetName()->Equals("<clinit>"));
+ EXPECT_TRUE(klass->GetDirectMethod(0)->IsDirect());
} else {
EXPECT_EQ(0U, klass->NumDirectMethods());
}
@@ -171,12 +172,14 @@
for (size_t i = 0; i < klass->NumDirectMethods(); i++) {
Method* method = klass->GetDirectMethod(i);
AssertMethod(klass, method);
+ EXPECT_TRUE(method->IsDirect());
EXPECT_EQ(klass, method->GetDeclaringClass());
}
for (size_t i = 0; i < klass->NumVirtualMethods(); i++) {
Method* method = klass->GetVirtualMethod(i);
AssertMethod(klass, method);
+ EXPECT_FALSE(method->IsDirect());
EXPECT_TRUE(method->GetDeclaringClass()->IsAssignableFrom(klass));
}
diff --git a/src/compiler.cc b/src/compiler.cc
index d1605a7..c8ff794 100644
--- a/src/compiler.cc
+++ b/src/compiler.cc
@@ -17,7 +17,7 @@
Resolve(class_loader);
// TODO add verification step
Compile(class_loader);
- SetCodeAndMethod(class_loader);
+ SetCodeAndDirectMethods(class_loader);
return class_loader;
}
@@ -104,23 +104,28 @@
// CHECK(method->HasCode()); // TODO: enable this check ASAP
}
-void Compiler::SetCodeAndMethod(const ClassLoader* class_loader) {
+void Compiler::SetCodeAndDirectMethods(const ClassLoader* class_loader) {
const std::vector<const DexFile*>& class_path = class_loader->GetClassPath();
for (size_t i = 0; i != class_path.size(); ++i) {
const DexFile* dex_file = class_path[i];
CHECK(dex_file != NULL);
- SetCodeAndMethodDexFile(class_loader, *dex_file);
+ SetCodeAndDirectMethodsDexFile(class_loader, *dex_file);
}
}
-void Compiler::SetCodeAndMethodDexFile(const ClassLoader* class_loader, const DexFile& dex_file) {
+void Compiler::SetCodeAndDirectMethodsDexFile(const ClassLoader* class_loader, const DexFile& dex_file) {
ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
DexCache* dex_cache = class_linker->FindDexCache(dex_file);
- CodeAndMethods* code_and_methods = dex_cache->GetCodeAndMethods();
+ CodeAndDirectMethods* code_and_direct_methods = dex_cache->GetCodeAndDirectMethods();
for (size_t i = 0; i < dex_cache->NumMethods(); i++) {
Method* method = dex_cache->GetResolvedMethod(i);
- if (method != NULL) {
- code_and_methods->SetResolvedMethod(i, method);
+ if (method == NULL) {
+ code_and_direct_methods->SetResolvedDirectMethodTrampoline(i);
+ } else if (method->IsDirect()) {
+ code_and_direct_methods->SetResolvedDirectMethod(i, method);
+ } else {
+ // TODO: we currently leave the entry blank for resolved
+ // non-direct methods. we could put in an error stub.
}
}
}
diff --git a/src/compiler.h b/src/compiler.h
index 864f29d..fde7a37 100644
--- a/src/compiler.h
+++ b/src/compiler.h
@@ -28,9 +28,9 @@
void CompileMethod(Method* klass);
// After compiling, walk all the DexCaches and set the code and
- // method pointers of CodeAndMethod entries in the DexCaches.
- void SetCodeAndMethod(const ClassLoader* class_loader);
- void SetCodeAndMethodDexFile(const ClassLoader* class_loader, const DexFile& dex_file);
+ // method pointers of CodeAndDirectMethods entries in the DexCaches.
+ void SetCodeAndDirectMethods(const ClassLoader* class_loader);
+ void SetCodeAndDirectMethodsDexFile(const ClassLoader* class_loader, const DexFile& dex_file);
};
} // namespace art
diff --git a/src/compiler_test.cc b/src/compiler_test.cc
index 6a2f81e..f6dc5c7 100644
--- a/src/compiler_test.cc
+++ b/src/compiler_test.cc
@@ -99,12 +99,12 @@
// TODO: check that all Method::GetCode() values are non-null
- EXPECT_EQ(dex->NumMethodIds(), dex_cache->NumCodeAndMethods());
- CodeAndMethods* code_and_methods = dex_cache->GetCodeAndMethods();
- for (size_t i = 0; i < dex_cache->NumCodeAndMethods(); i++) {
+ EXPECT_EQ(dex->NumMethodIds(), dex_cache->NumCodeAndDirectMethods());
+ CodeAndDirectMethods* code_and_direct_methods = dex_cache->GetCodeAndDirectMethods();
+ for (size_t i = 0; i < dex_cache->NumCodeAndDirectMethods(); i++) {
Method* method = dex_cache->GetResolvedMethod(i);
- EXPECT_EQ(method->GetCode(), code_and_methods->GetResolvedCode(i));
- EXPECT_EQ(method, code_and_methods->GetResolvedMethod(i));
+ EXPECT_EQ(method->GetCode(), code_and_direct_methods->GetResolvedCode(i));
+ EXPECT_EQ(method, code_and_direct_methods->GetResolvedMethod(i));
}
}
diff --git a/src/dex_cache.cc b/src/dex_cache.cc
index 88fbd2f..a4538c9 100644
--- a/src/dex_cache.cc
+++ b/src/dex_cache.cc
@@ -14,19 +14,19 @@
ObjectArray<Class>* types,
ObjectArray<Method>* methods,
ObjectArray<Field>* fields,
- CodeAndMethods* code_and_methods) {
+ CodeAndDirectMethods* code_and_direct_methods) {
CHECK(location != NULL);
CHECK(strings != NULL);
CHECK(types != NULL);
CHECK(methods != NULL);
CHECK(fields != NULL);
- CHECK(code_and_methods != NULL);
+ CHECK(code_and_direct_methods != NULL);
Set(kLocation, location);
Set(kStrings, strings);
Set(kTypes, types);
Set(kMethods, methods);
Set(kFields, fields);
- Set(kCodeAndMethods, code_and_methods);
+ Set(kCodeAndDirectMethods, code_and_direct_methods);
}
} // namespace art
diff --git a/src/dex_cache.h b/src/dex_cache.h
index 2f75c86..1e46a90 100644
--- a/src/dex_cache.h
+++ b/src/dex_cache.h
@@ -16,7 +16,7 @@
class String;
union JValue;
-class CodeAndMethods : public IntArray {
+class CodeAndDirectMethods : public IntArray {
public:
Method* GetResolvedCode(uint32_t method_idx) const {
return reinterpret_cast<Method*>(Get(method_idx * kMax + kCode));
@@ -25,8 +25,15 @@
return reinterpret_cast<byte*>(Get(method_idx * kMax + kMethod));
}
- void SetResolvedMethod(uint32_t method_idx, Method* method) {
+ void SetResolvedDirectMethodTrampoline(uint32_t method_idx) {
+ UNIMPLEMENTED(FATAL) << "need to install a trampoline to resolve the method_idx at runtime";
+ Set(method_idx * kMax + kCode, 0xffffffff);
+ Set(method_idx * kMax + kMethod, method_idx);
+ }
+
+ void SetResolvedDirectMethod(uint32_t method_idx, Method* method) {
CHECK(method != NULL);
+ CHECK(method->IsDirect());
// CHECK(method->GetCode() != NULL); // TODO enable when all code is compiling
Set(method_idx * kMax + kCode, reinterpret_cast<int32_t>(method->GetCode()));
Set(method_idx * kMax + kMethod, reinterpret_cast<int32_t>(method));
@@ -52,7 +59,7 @@
ObjectArray<Class>* types,
ObjectArray<Method>* methods,
ObjectArray<Field>* fields,
- CodeAndMethods* code_and_methods);
+ CodeAndDirectMethods* code_and_direct_methods);
String* GetLocation() const {
return Get(kLocation)->AsString();
@@ -89,8 +96,8 @@
return GetFields()->GetLength();
}
- size_t NumCodeAndMethods() const {
- return GetCodeAndMethods()->GetLength();
+ size_t NumCodeAndDirectMethods() const {
+ return GetCodeAndDirectMethods()->GetLength();
}
String* GetResolvedString(uint32_t string_idx) const {
@@ -137,8 +144,8 @@
ObjectArray<Field>* GetFields() const {
return static_cast<ObjectArray<Field>*>(GetNonNull(kFields));
}
- CodeAndMethods* GetCodeAndMethods() const {
- return static_cast<CodeAndMethods*>(GetNonNull(kCodeAndMethods));
+ CodeAndDirectMethods* GetCodeAndDirectMethods() const {
+ return static_cast<CodeAndDirectMethods*>(GetNonNull(kCodeAndDirectMethods));
}
static size_t LengthAsArray() {
@@ -148,13 +155,13 @@
private:
enum ArrayIndex {
- kLocation = 0,
- kStrings = 1,
- kTypes = 2,
- kMethods = 3,
- kFields = 4,
- kCodeAndMethods = 5,
- kMax = 6,
+ kLocation = 0,
+ kStrings = 1,
+ kTypes = 2,
+ kMethods = 3,
+ kFields = 4,
+ kCodeAndDirectMethods = 5,
+ kMax = 6,
};
Object* GetNonNull(ArrayIndex array_index) const {
diff --git a/src/object.h b/src/object.h
index 2cdfae2..51bf999 100644
--- a/src/object.h
+++ b/src/object.h
@@ -18,7 +18,7 @@
class Array;
class Class;
-class CodeAndMethods;
+class CodeAndDirectMethods;
class DexCache;
class Field;
class InterfaceEntry;
@@ -542,6 +542,10 @@
return shorty_[0] == 'V';
}
+ bool IsDirect() const {
+ return is_direct_;
+ }
+
// "Args" may refer to any of the 3 levels of "Args."
// To avoid confusion, our code will denote which "Args" clearly:
// 1. UserArgs: Args that a user see.
@@ -719,7 +723,9 @@
ObjectArray<Class>* dex_cache_types_;
ObjectArray<Method>* dex_cache_methods_;
ObjectArray<Field>* dex_cache_fields_;
- CodeAndMethods* dex_cache_code_and_methods_;
+ CodeAndDirectMethods* dex_cache_code_and_direct_methods_;
+
+ bool is_direct_;
private:
// Compiled code associated with this method