summaryrefslogtreecommitdiff
path: root/runtime/runtime_callbacks.cc
diff options
context:
space:
mode:
author Alex Light <allight@google.com> 2017-01-23 14:25:17 -0800
committer Alex Light <allight@google.com> 2017-01-23 14:44:23 -0800
commitb0f1192bfac159008e1f2367751083740ba05698 (patch)
tree4b5d4385c27b600f5488962d0f7f6f00d9836843 /runtime/runtime_callbacks.cc
parenta7e38d8aaacfca85b40b5df654f85c0979968672 (diff)
Add ClassPreDefine hook.
This hook is called prior to defining a class for the first time. It allows callbacks to modify the dex-file used to load the class if they wish. The event handler is responsible for ensuring that the returned dex-file is set-up correctly. Bug: 31684920 Test: mma -j40 test-art-host Change-Id: Iaed79c1597913148ead795e033a0a10a4ebe6b2b
Diffstat (limited to 'runtime/runtime_callbacks.cc')
-rw-r--r--runtime/runtime_callbacks.cc30
1 files changed, 30 insertions, 0 deletions
diff --git a/runtime/runtime_callbacks.cc b/runtime/runtime_callbacks.cc
index 7b15a4f1b5..25324b52d1 100644
--- a/runtime/runtime_callbacks.cc
+++ b/runtime/runtime_callbacks.cc
@@ -67,6 +67,36 @@ void RuntimeCallbacks::ClassLoad(Handle<mirror::Class> klass) {
}
}
+void RuntimeCallbacks::ClassPreDefine(const char* descriptor,
+ Handle<mirror::Class> temp_class,
+ Handle<mirror::ClassLoader> loader,
+ const DexFile& initial_dex_file,
+ const DexFile::ClassDef& initial_class_def,
+ /*out*/DexFile const** final_dex_file,
+ /*out*/DexFile::ClassDef const** final_class_def) {
+ DexFile const* current_dex_file = &initial_dex_file;
+ DexFile::ClassDef const* current_class_def = &initial_class_def;
+ for (ClassLoadCallback* cb : class_callbacks_) {
+ DexFile const* new_dex_file = nullptr;
+ DexFile::ClassDef const* new_class_def = nullptr;
+ cb->ClassPreDefine(descriptor,
+ temp_class,
+ loader,
+ *current_dex_file,
+ *current_class_def,
+ &new_dex_file,
+ &new_class_def);
+ if ((new_dex_file != nullptr && new_dex_file != current_dex_file) ||
+ (new_class_def != nullptr && new_class_def != current_class_def)) {
+ DCHECK(new_dex_file != nullptr && new_class_def != nullptr);
+ current_dex_file = new_dex_file;
+ current_class_def = new_class_def;
+ }
+ }
+ *final_dex_file = current_dex_file;
+ *final_class_def = current_class_def;
+}
+
void RuntimeCallbacks::ClassPrepare(Handle<mirror::Class> temp_klass, Handle<mirror::Class> klass) {
for (ClassLoadCallback* cb : class_callbacks_) {
cb->ClassPrepare(temp_klass, klass);