summaryrefslogtreecommitdiffstats
path: root/runtime/entrypoints
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/entrypoints')
-rw-r--r--runtime/entrypoints/interpreter/interpreter_entrypoints.cc11
-rw-r--r--runtime/entrypoints/portable/portable_alloc_entrypoints.cc76
-rw-r--r--runtime/entrypoints/portable/portable_cast_entrypoints.cc57
-rw-r--r--runtime/entrypoints/portable/portable_dexcache_entrypoints.cc53
-rw-r--r--runtime/entrypoints/portable/portable_entrypoints.h44
-rw-r--r--runtime/entrypoints/portable/portable_field_entrypoints.cc245
-rw-r--r--runtime/entrypoints/portable/portable_fillarray_entrypoints.cc35
-rw-r--r--runtime/entrypoints/portable/portable_invoke_entrypoints.cc118
-rw-r--r--runtime/entrypoints/portable/portable_jni_entrypoints.cc99
-rw-r--r--runtime/entrypoints/portable/portable_lock_entrypoints.cc40
-rw-r--r--runtime/entrypoints/portable/portable_thread_entrypoints.cc94
-rw-r--r--runtime/entrypoints/portable/portable_throw_entrypoints.cc128
-rw-r--r--runtime/entrypoints/portable/portable_trampoline_entrypoints.cc496
-rw-r--r--runtime/entrypoints/runtime_asm_entrypoints.h36
14 files changed, 4 insertions, 1528 deletions
diff --git a/runtime/entrypoints/interpreter/interpreter_entrypoints.cc b/runtime/entrypoints/interpreter/interpreter_entrypoints.cc
index 3b47f245f7..28e19d414d 100644
--- a/runtime/entrypoints/interpreter/interpreter_entrypoints.cc
+++ b/runtime/entrypoints/interpreter/interpreter_entrypoints.cc
@@ -15,6 +15,7 @@
*/
#include "class_linker.h"
+#include "dex_file-inl.h"
#include "interpreter/interpreter.h"
#include "mirror/art_method-inl.h"
#include "mirror/object-inl.h"
@@ -47,13 +48,9 @@ extern "C" void artInterpreterToCompiledCodeBridge(Thread* self, const DexFile::
}
}
uint16_t arg_offset = (code_item == NULL) ? 0 : code_item->registers_size_ - code_item->ins_size_;
- if (kUsePortableCompiler) {
- InvokeWithShadowFrame(self, shadow_frame, arg_offset, result);
- } else {
- method->Invoke(self, shadow_frame->GetVRegArgs(arg_offset),
- (shadow_frame->NumberOfVRegs() - arg_offset) * sizeof(uint32_t),
- result, method->GetShorty());
- }
+ method->Invoke(self, shadow_frame->GetVRegArgs(arg_offset),
+ (shadow_frame->NumberOfVRegs() - arg_offset) * sizeof(uint32_t),
+ result, method->GetShorty());
}
} // namespace art
diff --git a/runtime/entrypoints/portable/portable_alloc_entrypoints.cc b/runtime/entrypoints/portable/portable_alloc_entrypoints.cc
deleted file mode 100644
index de95f7dfbc..0000000000
--- a/runtime/entrypoints/portable/portable_alloc_entrypoints.cc
+++ /dev/null
@@ -1,76 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "entrypoints/entrypoint_utils-inl.h"
-#include "mirror/art_method-inl.h"
-#include "mirror/object-inl.h"
-
-namespace art {
-
-static constexpr gc::AllocatorType kPortableAllocatorType =
- gc::kUseRosAlloc ? gc::kAllocatorTypeRosAlloc : gc::kAllocatorTypeDlMalloc;
-
-extern "C" mirror::Object* art_portable_alloc_object_from_code(uint32_t type_idx,
- mirror::ArtMethod* referrer,
- Thread* thread)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return AllocObjectFromCode<false, true>(type_idx, referrer, thread, kPortableAllocatorType);
-}
-
-extern "C" mirror::Object* art_portable_alloc_object_from_code_with_access_check(uint32_t type_idx,
- mirror::ArtMethod* referrer,
- Thread* thread)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return AllocObjectFromCode<true, true>(type_idx, referrer, thread, kPortableAllocatorType);
-}
-
-extern "C" mirror::Object* art_portable_alloc_array_from_code(uint32_t type_idx,
- mirror::ArtMethod* referrer,
- uint32_t length,
- Thread* self)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return AllocArrayFromCode<false, true>(type_idx, referrer, length, self,
- kPortableAllocatorType);
-}
-
-extern "C" mirror::Object* art_portable_alloc_array_from_code_with_access_check(uint32_t type_idx,
- mirror::ArtMethod* referrer,
- uint32_t length,
- Thread* self)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return AllocArrayFromCode<true, true>(type_idx, referrer, length, self,
- kPortableAllocatorType);
-}
-
-extern "C" mirror::Object* art_portable_check_and_alloc_array_from_code(uint32_t type_idx,
- mirror::ArtMethod* referrer,
- uint32_t length,
- Thread* thread)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return CheckAndAllocArrayFromCodeInstrumented(type_idx, referrer, length, thread, false,
- kPortableAllocatorType);
-}
-
-extern "C" mirror::Object* art_portable_check_and_alloc_array_from_code_with_access_check(uint32_t type_idx,
- mirror::ArtMethod* referrer,
- uint32_t length,
- Thread* thread)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return CheckAndAllocArrayFromCodeInstrumented(type_idx, referrer, length, thread, true,
- kPortableAllocatorType);
-}
-
-} // namespace art
diff --git a/runtime/entrypoints/portable/portable_cast_entrypoints.cc b/runtime/entrypoints/portable/portable_cast_entrypoints.cc
deleted file mode 100644
index 151b1785c9..0000000000
--- a/runtime/entrypoints/portable/portable_cast_entrypoints.cc
+++ /dev/null
@@ -1,57 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "common_throws.h"
-#include "entrypoints/entrypoint_utils-inl.h"
-#include "mirror/object-inl.h"
-
-namespace art {
-
-extern "C" int32_t art_portable_is_assignable_from_code(mirror::Class* dest_type,
- mirror::Class* src_type)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DCHECK(dest_type != NULL);
- DCHECK(src_type != NULL);
- return dest_type->IsAssignableFrom(src_type) ? 1 : 0;
-}
-
-extern "C" void art_portable_check_cast_from_code(mirror::Class* dest_type,
- mirror::Class* src_type)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DCHECK(dest_type->IsClass()) << PrettyClass(dest_type);
- DCHECK(src_type->IsClass()) << PrettyClass(src_type);
- if (UNLIKELY(!dest_type->IsAssignableFrom(src_type))) {
- ThrowClassCastException(dest_type, src_type);
- }
-}
-
-extern "C" void art_portable_check_put_array_element_from_code(mirror::Object* element,
- mirror::Object* array)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- if (element == NULL) {
- return;
- }
- DCHECK(array != NULL);
- mirror::Class* array_class = array->GetClass();
- DCHECK(array_class != NULL);
- mirror::Class* component_type = array_class->GetComponentType();
- mirror::Class* element_class = element->GetClass();
- if (UNLIKELY(!component_type->IsAssignableFrom(element_class))) {
- ThrowArrayStoreException(element_class, array_class);
- }
-}
-
-} // namespace art
diff --git a/runtime/entrypoints/portable/portable_dexcache_entrypoints.cc b/runtime/entrypoints/portable/portable_dexcache_entrypoints.cc
deleted file mode 100644
index 9364c46abf..0000000000
--- a/runtime/entrypoints/portable/portable_dexcache_entrypoints.cc
+++ /dev/null
@@ -1,53 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "entrypoints/entrypoint_utils-inl.h"
-#include "gc/accounting/card_table-inl.h"
-#include "mirror/art_method-inl.h"
-#include "mirror/object-inl.h"
-
-namespace art {
-
-extern "C" mirror::Object* art_portable_initialize_static_storage_from_code(uint32_t type_idx,
- mirror::ArtMethod* referrer,
- Thread* thread)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return ResolveVerifyAndClinit(type_idx, referrer, thread, true, false);
-}
-
-extern "C" mirror::Object* art_portable_initialize_type_from_code(uint32_t type_idx,
- mirror::ArtMethod* referrer,
- Thread* thread)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return ResolveVerifyAndClinit(type_idx, referrer, thread, false, false);
-}
-
-extern "C" mirror::Object* art_portable_initialize_type_and_verify_access_from_code(uint32_t type_idx,
- mirror::ArtMethod* referrer,
- Thread* thread)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- // Called when caller isn't guaranteed to have access to a type and the dex cache may be
- // unpopulated
- return ResolveVerifyAndClinit(type_idx, referrer, thread, false, true);
-}
-
-extern "C" mirror::Object* art_portable_resolve_string_from_code(mirror::ArtMethod* referrer,
- uint32_t string_idx)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return ResolveStringFromCode(referrer, string_idx);
-}
-
-} // namespace art
diff --git a/runtime/entrypoints/portable/portable_entrypoints.h b/runtime/entrypoints/portable/portable_entrypoints.h
deleted file mode 100644
index 6f77e1c42b..0000000000
--- a/runtime/entrypoints/portable/portable_entrypoints.h
+++ /dev/null
@@ -1,44 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_RUNTIME_ENTRYPOINTS_PORTABLE_PORTABLE_ENTRYPOINTS_H_
-#define ART_RUNTIME_ENTRYPOINTS_PORTABLE_PORTABLE_ENTRYPOINTS_H_
-
-#include "dex_file-inl.h"
-#include "runtime.h"
-
-namespace art {
-namespace mirror {
- class ArtMethod;
- class Object;
-} // namespace mirror
-class Thread;
-
-#define PORTABLE_ENTRYPOINT_OFFSET(ptr_size, x) \
- Thread::PortableEntryPointOffset<ptr_size>(OFFSETOF_MEMBER(PortableEntryPoints, x))
-
-// Pointers to functions that are called by code generated by compiler's adhering to the portable
-// compiler ABI.
-struct PACKED(4) PortableEntryPoints {
- // Invocation
- void (*pPortableImtConflictTrampoline)(mirror::ArtMethod*);
- void (*pPortableResolutionTrampoline)(mirror::ArtMethod*);
- void (*pPortableToInterpreterBridge)(mirror::ArtMethod*);
-};
-
-} // namespace art
-
-#endif // ART_RUNTIME_ENTRYPOINTS_PORTABLE_PORTABLE_ENTRYPOINTS_H_
diff --git a/runtime/entrypoints/portable/portable_field_entrypoints.cc b/runtime/entrypoints/portable/portable_field_entrypoints.cc
deleted file mode 100644
index 371aca4b2d..0000000000
--- a/runtime/entrypoints/portable/portable_field_entrypoints.cc
+++ /dev/null
@@ -1,245 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "entrypoints/entrypoint_utils-inl.h"
-#include "mirror/art_field-inl.h"
-#include "mirror/art_method-inl.h"
-#include "mirror/object-inl.h"
-
-namespace art {
-
-extern "C" int32_t art_portable_set32_static_from_code(uint32_t field_idx,
- mirror::ArtMethod* referrer,
- int32_t new_value)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- mirror::ArtField* field = FindFieldFast(field_idx,
- referrer,
- StaticPrimitiveWrite,
- sizeof(uint32_t));
- if (LIKELY(field != NULL)) {
- // Compiled code can't use transactional mode.
- field->Set32<false>(field->GetDeclaringClass(), new_value);
- return 0;
- }
- field = FindFieldFromCode<StaticPrimitiveWrite, true>(field_idx, referrer, Thread::Current(),
- sizeof(uint32_t));
- if (LIKELY(field != NULL)) {
- // Compiled code can't use transactional mode.
- field->Set32<false>(field->GetDeclaringClass(), new_value);
- return 0;
- }
- return -1;
-}
-
-extern "C" int32_t art_portable_set64_static_from_code(uint32_t field_idx,
- mirror::ArtMethod* referrer,
- int64_t new_value)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveWrite, sizeof(uint64_t));
- if (LIKELY(field != NULL)) {
- // Compiled code can't use transactional mode.
- field->Set64<false>(field->GetDeclaringClass(), new_value);
- return 0;
- }
- field = FindFieldFromCode<StaticPrimitiveWrite, true>(field_idx, referrer, Thread::Current(),
- sizeof(uint64_t));
- if (LIKELY(field != NULL)) {
- // Compiled code can't use transactional mode.
- field->Set64<false>(field->GetDeclaringClass(), new_value);
- return 0;
- }
- return -1;
-}
-
-extern "C" int32_t art_portable_set_obj_static_from_code(uint32_t field_idx,
- mirror::ArtMethod* referrer,
- mirror::Object* new_value)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticObjectWrite,
- sizeof(mirror::HeapReference<mirror::Object>));
- if (LIKELY(field != NULL)) {
- // Compiled code can't use transactional mode.
- field->SetObj<false>(field->GetDeclaringClass(), new_value);
- return 0;
- }
- field = FindFieldFromCode<StaticObjectWrite, true>(field_idx, referrer, Thread::Current(),
- sizeof(mirror::HeapReference<mirror::Object>));
- if (LIKELY(field != NULL)) {
- // Compiled code can't use transactional mode.
- field->SetObj<false>(field->GetDeclaringClass(), new_value);
- return 0;
- }
- return -1;
-}
-
-extern "C" int32_t art_portable_get32_static_from_code(uint32_t field_idx,
- mirror::ArtMethod* referrer)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(uint32_t));
- if (LIKELY(field != NULL)) {
- return field->Get32(field->GetDeclaringClass());
- }
- field = FindFieldFromCode<StaticPrimitiveRead, true>(field_idx, referrer, Thread::Current(),
- sizeof(uint32_t));
- if (LIKELY(field != NULL)) {
- return field->Get32(field->GetDeclaringClass());
- }
- return 0;
-}
-
-extern "C" int64_t art_portable_get64_static_from_code(uint32_t field_idx,
- mirror::ArtMethod* referrer)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticPrimitiveRead, sizeof(uint64_t));
- if (LIKELY(field != NULL)) {
- return field->Get64(field->GetDeclaringClass());
- }
- field = FindFieldFromCode<StaticPrimitiveRead, true>(field_idx, referrer, Thread::Current(),
- sizeof(uint64_t));
- if (LIKELY(field != NULL)) {
- return field->Get64(field->GetDeclaringClass());
- }
- return 0;
-}
-
-extern "C" mirror::Object* art_portable_get_obj_static_from_code(uint32_t field_idx,
- mirror::ArtMethod* referrer)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, StaticObjectRead,
- sizeof(mirror::HeapReference<mirror::Object>));
- if (LIKELY(field != NULL)) {
- return field->GetObj(field->GetDeclaringClass());
- }
- field = FindFieldFromCode<StaticObjectRead, true>(field_idx, referrer, Thread::Current(),
- sizeof(mirror::HeapReference<mirror::Object>));
- if (LIKELY(field != NULL)) {
- return field->GetObj(field->GetDeclaringClass());
- }
- return 0;
-}
-
-extern "C" int32_t art_portable_set32_instance_from_code(uint32_t field_idx,
- mirror::ArtMethod* referrer,
- mirror::Object* obj, uint32_t new_value)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(uint32_t));
- if (LIKELY(field != NULL)) {
- // Compiled code can't use transactional mode.
- field->Set32<false>(obj, new_value);
- return 0;
- }
- field = FindFieldFromCode<InstancePrimitiveWrite, true>(field_idx, referrer, Thread::Current(),
- sizeof(uint32_t));
- if (LIKELY(field != NULL)) {
- // Compiled code can't use transactional mode.
- field->Set32<false>(obj, new_value);
- return 0;
- }
- return -1;
-}
-
-extern "C" int32_t art_portable_set64_instance_from_code(uint32_t field_idx,
- mirror::ArtMethod* referrer,
- mirror::Object* obj, int64_t new_value)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveWrite, sizeof(uint64_t));
- if (LIKELY(field != NULL)) {
- // Compiled code can't use transactional mode.
- field->Set64<false>(obj, new_value);
- return 0;
- }
- field = FindFieldFromCode<InstancePrimitiveWrite, true>(field_idx, referrer, Thread::Current(),
- sizeof(uint64_t));
- if (LIKELY(field != NULL)) {
- // Compiled code can't use transactional mode.
- field->Set64<false>(obj, new_value);
- return 0;
- }
- return -1;
-}
-
-extern "C" int32_t art_portable_set_obj_instance_from_code(uint32_t field_idx,
- mirror::ArtMethod* referrer,
- mirror::Object* obj,
- mirror::Object* new_value)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstanceObjectWrite,
- sizeof(mirror::HeapReference<mirror::Object>));
- if (LIKELY(field != NULL)) {
- // Compiled code can't use transactional mode.
- field->SetObj<false>(obj, new_value);
- return 0;
- }
- field = FindFieldFromCode<InstanceObjectWrite, true>(field_idx, referrer, Thread::Current(),
- sizeof(mirror::HeapReference<mirror::Object>));
- if (LIKELY(field != NULL)) {
- // Compiled code can't use transactional mode.
- field->SetObj<false>(obj, new_value);
- return 0;
- }
- return -1;
-}
-
-extern "C" int32_t art_portable_get32_instance_from_code(uint32_t field_idx,
- mirror::ArtMethod* referrer,
- mirror::Object* obj)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(uint32_t));
- if (LIKELY(field != NULL)) {
- return field->Get32(obj);
- }
- field = FindFieldFromCode<InstancePrimitiveRead, true>(field_idx, referrer, Thread::Current(),
- sizeof(uint32_t));
- if (LIKELY(field != NULL)) {
- return field->Get32(obj);
- }
- return 0;
-}
-
-extern "C" int64_t art_portable_get64_instance_from_code(uint32_t field_idx,
- mirror::ArtMethod* referrer,
- mirror::Object* obj)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstancePrimitiveRead, sizeof(uint64_t));
- if (LIKELY(field != NULL)) {
- return field->Get64(obj);
- }
- field = FindFieldFromCode<InstancePrimitiveRead, true>(field_idx, referrer, Thread::Current(),
- sizeof(uint64_t));
- if (LIKELY(field != NULL)) {
- return field->Get64(obj);
- }
- return 0;
-}
-
-extern "C" mirror::Object* art_portable_get_obj_instance_from_code(uint32_t field_idx,
- mirror::ArtMethod* referrer,
- mirror::Object* obj)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- mirror::ArtField* field = FindFieldFast(field_idx, referrer, InstanceObjectRead,
- sizeof(mirror::HeapReference<mirror::Object>));
- if (LIKELY(field != NULL)) {
- return field->GetObj(obj);
- }
- field = FindFieldFromCode<InstanceObjectRead, true>(field_idx, referrer, Thread::Current(),
- sizeof(mirror::HeapReference<mirror::Object>));
- if (LIKELY(field != NULL)) {
- return field->GetObj(obj);
- }
- return 0;
-}
-
-} // namespace art
diff --git a/runtime/entrypoints/portable/portable_fillarray_entrypoints.cc b/runtime/entrypoints/portable/portable_fillarray_entrypoints.cc
deleted file mode 100644
index afe769e5ec..0000000000
--- a/runtime/entrypoints/portable/portable_fillarray_entrypoints.cc
+++ /dev/null
@@ -1,35 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "dex_instruction.h"
-#include "entrypoints/entrypoint_utils.h"
-#include "mirror/art_method-inl.h"
-
-namespace art {
-
-extern "C" void art_portable_fill_array_data_from_code(mirror::ArtMethod* method,
- uint32_t dex_pc,
- mirror::Array* array,
- uint32_t payload_offset)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- UNUSED(dex_pc);
- const DexFile::CodeItem* code_item = method->GetCodeItem();
- const Instruction::ArrayDataPayload* payload =
- reinterpret_cast<const Instruction::ArrayDataPayload*>(code_item->insns_ + payload_offset);
- FillArrayData(array, payload);
-}
-
-} // namespace art
diff --git a/runtime/entrypoints/portable/portable_invoke_entrypoints.cc b/runtime/entrypoints/portable/portable_invoke_entrypoints.cc
deleted file mode 100644
index 6f9c083c80..0000000000
--- a/runtime/entrypoints/portable/portable_invoke_entrypoints.cc
+++ /dev/null
@@ -1,118 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "entrypoints/entrypoint_utils-inl.h"
-#include "mirror/art_method-inl.h"
-#include "mirror/dex_cache-inl.h"
-#include "mirror/object-inl.h"
-
-namespace art {
-
-template<InvokeType type, bool access_check>
-mirror::ArtMethod* FindMethodHelper(uint32_t method_idx, mirror::Object* this_object,
- mirror::ArtMethod* caller_method, Thread* self) {
- mirror::ArtMethod* method = FindMethodFast(method_idx, this_object, caller_method,
- access_check, type);
- if (UNLIKELY(method == NULL)) {
- // Note: This can cause thread suspension.
- self->AssertThreadSuspensionIsAllowable();
- method = FindMethodFromCode<type, access_check>(method_idx, &this_object, &caller_method,
- self);
- if (UNLIKELY(method == NULL)) {
- CHECK(self->IsExceptionPending());
- return 0; // failure
- }
- }
- DCHECK(!self->IsExceptionPending());
- const void* code = method->GetEntryPointFromPortableCompiledCode();
-
- // When we return, the caller will branch to this address, so it had better not be 0!
- if (UNLIKELY(code == NULL)) {
- LOG(FATAL) << "Code was NULL in method: " << PrettyMethod(method)
- << " location: " << method->GetDexFile()->GetLocation();
- }
- return method;
-}
-
-// Explicit template declarations of FindMethodHelper for all invoke types.
-#define EXPLICIT_FIND_METHOD_HELPER_TEMPLATE_DECL(_type, _access_check) \
- template SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) \
- mirror::ArtMethod* FindMethodHelper<_type, _access_check>(uint32_t method_idx, \
- mirror::Object* this_object, \
- mirror::ArtMethod* caller_method, \
- Thread* thread)
-#define EXPLICIT_FIND_METHOD_HELPER_TYPED_TEMPLATE_DECL(_type) \
- EXPLICIT_FIND_METHOD_HELPER_TEMPLATE_DECL(_type, false); \
- EXPLICIT_FIND_METHOD_HELPER_TEMPLATE_DECL(_type, true)
-
-EXPLICIT_FIND_METHOD_HELPER_TYPED_TEMPLATE_DECL(kStatic);
-EXPLICIT_FIND_METHOD_HELPER_TYPED_TEMPLATE_DECL(kDirect);
-EXPLICIT_FIND_METHOD_HELPER_TYPED_TEMPLATE_DECL(kVirtual);
-EXPLICIT_FIND_METHOD_HELPER_TYPED_TEMPLATE_DECL(kSuper);
-EXPLICIT_FIND_METHOD_HELPER_TYPED_TEMPLATE_DECL(kInterface);
-
-#undef EXPLICIT_FIND_METHOD_HELPER_TYPED_TEMPLATE_DECL
-#undef EXPLICIT_FIND_METHOD_HELPER_TEMPLATE_DECL
-
-extern "C" mirror::Object* art_portable_find_static_method_from_code_with_access_check(uint32_t method_idx,
- mirror::Object* this_object,
- mirror::ArtMethod* referrer,
- Thread* thread)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return FindMethodHelper<kStatic, true>(method_idx, this_object, referrer, thread);
-}
-
-extern "C" mirror::Object* art_portable_find_direct_method_from_code_with_access_check(uint32_t method_idx,
- mirror::Object* this_object,
- mirror::ArtMethod* referrer,
- Thread* thread)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return FindMethodHelper<kDirect, true>(method_idx, this_object, referrer, thread);
-}
-
-extern "C" mirror::Object* art_portable_find_virtual_method_from_code_with_access_check(uint32_t method_idx,
- mirror::Object* this_object,
- mirror::ArtMethod* referrer,
- Thread* thread)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return FindMethodHelper<kVirtual, true>(method_idx, this_object, referrer, thread);
-}
-
-extern "C" mirror::Object* art_portable_find_super_method_from_code_with_access_check(uint32_t method_idx,
- mirror::Object* this_object,
- mirror::ArtMethod* referrer,
- Thread* thread)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return FindMethodHelper<kSuper, true>(method_idx, this_object, referrer, thread);
-}
-
-extern "C" mirror::Object* art_portable_find_interface_method_from_code_with_access_check(uint32_t method_idx,
- mirror::Object* this_object,
- mirror::ArtMethod* referrer,
- Thread* thread)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return FindMethodHelper<kInterface, true>(method_idx, this_object, referrer, thread);
-}
-
-extern "C" mirror::Object* art_portable_find_interface_method_from_code(uint32_t method_idx,
- mirror::Object* this_object,
- mirror::ArtMethod* referrer,
- Thread* thread)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return FindMethodHelper<kInterface, false>(method_idx, this_object, referrer, thread);
-}
-
-} // namespace art
diff --git a/runtime/entrypoints/portable/portable_jni_entrypoints.cc b/runtime/entrypoints/portable/portable_jni_entrypoints.cc
deleted file mode 100644
index 0d0f21b795..0000000000
--- a/runtime/entrypoints/portable/portable_jni_entrypoints.cc
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "entrypoints/entrypoint_utils-inl.h"
-#include "mirror/art_method-inl.h"
-#include "mirror/object-inl.h"
-#include "thread-inl.h"
-
-namespace art {
-
-// Called on entry to JNI, transition out of Runnable and release share of mutator_lock_.
-extern "C" uint32_t art_portable_jni_method_start(Thread* self)
- UNLOCK_FUNCTION(Locks::mutator_lock_) {
- JNIEnvExt* env = self->GetJniEnv();
- uint32_t saved_local_ref_cookie = env->local_ref_cookie;
- env->local_ref_cookie = env->locals.GetSegmentState();
- self->TransitionFromRunnableToSuspended(kNative);
- return saved_local_ref_cookie;
-}
-
-extern "C" uint32_t art_portable_jni_method_start_synchronized(jobject to_lock, Thread* self)
- UNLOCK_FUNCTION(Locks::mutator_lock_) NO_THREAD_SAFETY_ANALYSIS {
- self->DecodeJObject(to_lock)->MonitorEnter(self);
- return art_portable_jni_method_start(self);
-}
-
-static void PopLocalReferences(uint32_t saved_local_ref_cookie, Thread* self)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- JNIEnvExt* env = self->GetJniEnv();
- env->locals.SetSegmentState(env->local_ref_cookie);
- env->local_ref_cookie = saved_local_ref_cookie;
-}
-
-extern "C" void art_portable_jni_method_end(uint32_t saved_local_ref_cookie, Thread* self)
- SHARED_LOCK_FUNCTION(Locks::mutator_lock_) {
- self->TransitionFromSuspendedToRunnable();
- PopLocalReferences(saved_local_ref_cookie, self);
-}
-
-
-extern "C" void art_portable_jni_method_end_synchronized(uint32_t saved_local_ref_cookie,
- jobject locked,
- Thread* self)
- SHARED_LOCK_FUNCTION(Locks::mutator_lock_) {
- self->TransitionFromSuspendedToRunnable();
- UnlockJniSynchronizedMethod(locked, self); // Must decode before pop.
- PopLocalReferences(saved_local_ref_cookie, self);
-}
-
-extern "C" mirror::Object* art_portable_jni_method_end_with_reference(jobject result,
- uint32_t saved_local_ref_cookie,
- Thread* self)
- SHARED_LOCK_FUNCTION(Locks::mutator_lock_) {
- self->TransitionFromSuspendedToRunnable();
- mirror::Object* o = self->DecodeJObject(result); // Must decode before pop.
- PopLocalReferences(saved_local_ref_cookie, self);
- // Process result.
- if (UNLIKELY(self->GetJniEnv()->check_jni)) {
- if (self->IsExceptionPending()) {
- return NULL;
- }
- CheckReferenceResult(o, self);
- }
- return o;
-}
-
-extern "C" mirror::Object* art_portable_jni_method_end_with_reference_synchronized(jobject result,
- uint32_t saved_local_ref_cookie,
- jobject locked,
- Thread* self)
- SHARED_LOCK_FUNCTION(Locks::mutator_lock_) {
- self->TransitionFromSuspendedToRunnable();
- UnlockJniSynchronizedMethod(locked, self); // Must decode before pop.
- mirror::Object* o = self->DecodeJObject(result);
- PopLocalReferences(saved_local_ref_cookie, self);
- // Process result.
- if (UNLIKELY(self->GetJniEnv()->check_jni)) {
- if (self->IsExceptionPending()) {
- return NULL;
- }
- CheckReferenceResult(o, self);
- }
- return o;
-}
-
-} // namespace art
diff --git a/runtime/entrypoints/portable/portable_lock_entrypoints.cc b/runtime/entrypoints/portable/portable_lock_entrypoints.cc
deleted file mode 100644
index fcd3e9d49e..0000000000
--- a/runtime/entrypoints/portable/portable_lock_entrypoints.cc
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "entrypoints/entrypoint_utils-inl.h"
-#include "mirror/object-inl.h"
-
-namespace art {
-
-extern "C" void art_portable_lock_object_from_code(mirror::Object* obj, Thread* thread)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
- NO_THREAD_SAFETY_ANALYSIS /* EXCLUSIVE_LOCK_FUNCTION(Monitor::monitor_lock_) */ {
- DCHECK(obj != nullptr); // Assumed to have been checked before entry.
- obj->MonitorEnter(thread); // May block.
- DCHECK(thread->HoldsLock(obj));
- // Only possible exception is NPE and is handled before entry.
- DCHECK(!thread->IsExceptionPending());
-}
-
-extern "C" void art_portable_unlock_object_from_code(mirror::Object* obj, Thread* thread)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_)
- NO_THREAD_SAFETY_ANALYSIS /* UNLOCK_FUNCTION(Monitor::monitor_lock_) */ {
- DCHECK(obj != nullptr); // Assumed to have been checked before entry.
- // MonitorExit may throw exception.
- obj->MonitorExit(thread);
-}
-
-} // namespace art
diff --git a/runtime/entrypoints/portable/portable_thread_entrypoints.cc b/runtime/entrypoints/portable/portable_thread_entrypoints.cc
deleted file mode 100644
index 95ac66cbec..0000000000
--- a/runtime/entrypoints/portable/portable_thread_entrypoints.cc
+++ /dev/null
@@ -1,94 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "mirror/art_method-inl.h"
-#include "verifier/dex_gc_map.h"
-#include "stack.h"
-#include "thread-inl.h"
-
-namespace art {
-
-class ShadowFrameCopyVisitor : public StackVisitor {
- public:
- explicit ShadowFrameCopyVisitor(Thread* self) : StackVisitor(self, NULL), prev_frame_(NULL),
- top_frame_(NULL) {}
-
- bool VisitFrame() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- if (IsShadowFrame()) {
- ShadowFrame* cur_frame = GetCurrentShadowFrame();
- size_t num_regs = cur_frame->NumberOfVRegs();
- mirror::ArtMethod* method = cur_frame->GetMethod();
- uint32_t dex_pc = cur_frame->GetDexPC();
- ShadowFrame* new_frame = ShadowFrame::Create(num_regs, NULL, method, dex_pc);
-
- const uint8_t* gc_map = method->GetNativeGcMap(sizeof(void*));
- verifier::DexPcToReferenceMap dex_gc_map(gc_map);
- const uint8_t* reg_bitmap = dex_gc_map.FindBitMap(dex_pc);
- for (size_t reg = 0; reg < num_regs; ++reg) {
- if (TestBitmap(reg, reg_bitmap)) {
- new_frame->SetVRegReference(reg, cur_frame->GetVRegReference(reg));
- } else {
- new_frame->SetVReg(reg, cur_frame->GetVReg(reg));
- }
- }
-
- if (prev_frame_ != NULL) {
- prev_frame_->SetLink(new_frame);
- } else {
- top_frame_ = new_frame;
- }
- prev_frame_ = new_frame;
- }
- return true;
- }
-
- ShadowFrame* GetShadowFrameCopy() {
- return top_frame_;
- }
-
- private:
- static bool TestBitmap(int reg, const uint8_t* reg_vector) {
- return ((reg_vector[reg / 8] >> (reg % 8)) & 0x01) != 0;
- }
-
- ShadowFrame* prev_frame_;
- ShadowFrame* top_frame_;
-};
-
-extern "C" void art_portable_test_suspend_from_code(Thread* self)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- self->CheckSuspend();
- if (Runtime::Current()->GetInstrumentation()->ShouldPortableCodeDeoptimize()) {
- // Save out the shadow frame to the heap
- ShadowFrameCopyVisitor visitor(self);
- visitor.WalkStack(true);
- self->SetDeoptimizationShadowFrame(visitor.GetShadowFrameCopy());
- self->SetDeoptimizationReturnValue(JValue());
- self->SetException(ThrowLocation(), Thread::GetDeoptimizationException());
- }
-}
-
-extern "C" ShadowFrame* art_portable_push_shadow_frame_from_code(Thread* thread,
- ShadowFrame* new_shadow_frame,
- mirror::ArtMethod* method,
- uint32_t num_vregs) {
- ShadowFrame* old_frame = thread->PushShadowFrame(new_shadow_frame);
- new_shadow_frame->SetMethod(method);
- new_shadow_frame->SetNumberOfVRegs(num_vregs);
- return old_frame;
-}
-
-} // namespace art
diff --git a/runtime/entrypoints/portable/portable_throw_entrypoints.cc b/runtime/entrypoints/portable/portable_throw_entrypoints.cc
deleted file mode 100644
index 431735803d..0000000000
--- a/runtime/entrypoints/portable/portable_throw_entrypoints.cc
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * Copyright (C) 2012 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#include "dex_instruction.h"
-#include "entrypoints/entrypoint_utils-inl.h"
-#include "mirror/art_method-inl.h"
-#include "mirror/object-inl.h"
-
-namespace art {
-
-extern "C" void art_portable_throw_div_zero_from_code() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ThrowArithmeticExceptionDivideByZero();
-}
-
-extern "C" void art_portable_throw_array_bounds_from_code(int32_t index, int32_t length)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ThrowArrayIndexOutOfBoundsException(index, length);
-}
-
-extern "C" void art_portable_throw_no_such_method_from_code(int32_t method_idx)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ThrowNoSuchMethodError(method_idx);
-}
-
-extern "C" void art_portable_throw_null_pointer_exception_from_code(uint32_t dex_pc)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- // TODO: remove dex_pc argument from caller.
- UNUSED(dex_pc);
- Thread* self = Thread::Current();
- ThrowLocation throw_location = self->GetCurrentLocationForThrow();
- ThrowNullPointerExceptionFromDexPC(throw_location);
-}
-
-extern "C" void art_portable_throw_stack_overflow_from_code() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- ThrowStackOverflowError(Thread::Current());
-}
-
-extern "C" void art_portable_throw_exception_from_code(mirror::Throwable* exception)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Thread* self = Thread::Current();
- ThrowLocation throw_location = self->GetCurrentLocationForThrow();
- if (exception == NULL) {
- ThrowNullPointerException(NULL, "throw with null exception");
- } else {
- self->SetException(throw_location, exception);
- }
-}
-
-extern "C" void* art_portable_get_and_clear_exception(Thread* self)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- DCHECK(self->IsExceptionPending());
- // TODO: make this inline.
- mirror::Throwable* exception = self->GetException(NULL);
- self->ClearException();
- return exception;
-}
-
-extern "C" int32_t art_portable_find_catch_block_from_code(mirror::ArtMethod* current_method,
- uint32_t ti_offset)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Thread* self = Thread::Current(); // TODO: make an argument.
- ThrowLocation throw_location;
- mirror::Throwable* exception = self->GetException(&throw_location);
- // Check for special deoptimization exception.
- if (UNLIKELY(reinterpret_cast<intptr_t>(exception) == -1)) {
- return -1;
- }
- mirror::Class* exception_type = exception->GetClass();
- StackHandleScope<1> hs(self);
- const DexFile::CodeItem* code_item = current_method->GetCodeItem();
- DCHECK_LT(ti_offset, code_item->tries_size_);
- const DexFile::TryItem* try_item = DexFile::GetTryItems(*code_item, ti_offset);
-
- int iter_index = 0;
- int result = -1;
- uint32_t catch_dex_pc = -1;
- // Iterate over the catch handlers associated with dex_pc
- for (CatchHandlerIterator it(*code_item, *try_item); it.HasNext(); it.Next()) {
- uint16_t iter_type_idx = it.GetHandlerTypeIndex();
- // Catch all case
- if (iter_type_idx == DexFile::kDexNoIndex16) {
- catch_dex_pc = it.GetHandlerAddress();
- result = iter_index;
- break;
- }
- // Does this catch exception type apply?
- mirror::Class* iter_exception_type =
- current_method->GetDexCacheResolvedType(iter_type_idx);
- if (UNLIKELY(iter_exception_type == NULL)) {
- // TODO: check, the verifier (class linker?) should take care of resolving all exception
- // classes early.
- LOG(WARNING) << "Unresolved exception class when finding catch block: "
- << current_method->GetTypeDescriptorFromTypeIdx(iter_type_idx);
- } else if (iter_exception_type->IsAssignableFrom(exception_type)) {
- catch_dex_pc = it.GetHandlerAddress();
- result = iter_index;
- break;
- }
- ++iter_index;
- }
- if (result != -1) {
- // Handler found.
- Runtime::Current()->GetInstrumentation()->ExceptionCaughtEvent(
- self, throw_location, current_method, catch_dex_pc, exception);
- // If the catch block has no move-exception then clear the exception for it.
- const Instruction* first_catch_instr = Instruction::At(
- &current_method->GetCodeItem()->insns_[catch_dex_pc]);
- if (first_catch_instr->Opcode() != Instruction::MOVE_EXCEPTION) {
- self->ClearException();
- }
- }
- return result;
-}
-
-} // namespace art
diff --git a/runtime/entrypoints/portable/portable_trampoline_entrypoints.cc b/runtime/entrypoints/portable/portable_trampoline_entrypoints.cc
deleted file mode 100644
index 2a2771f31c..0000000000
--- a/runtime/entrypoints/portable/portable_trampoline_entrypoints.cc
+++ /dev/null
@@ -1,496 +0,0 @@
-/*
- * Copyright (C) 2013 The Android Open Source Project
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-#ifndef ART_RUNTIME_ENTRYPOINTS_PORTABLE_PORTABLE_ARGUMENT_VISITOR_H_
-#define ART_RUNTIME_ENTRYPOINTS_PORTABLE_PORTABLE_ARGUMENT_VISITOR_H_
-
-#include "dex_instruction-inl.h"
-#include "entrypoints/entrypoint_utils-inl.h"
-#include "entrypoints/runtime_asm_entrypoints.h"
-#include "interpreter/interpreter.h"
-#include "mirror/art_method-inl.h"
-#include "mirror/object-inl.h"
-#include "scoped_thread_state_change.h"
-
-namespace art {
-
-class ShortyHelper {
- public:
- ShortyHelper(const char* shorty, uint32_t shorty_len, bool is_static)
- : shorty_(shorty), shorty_len_(shorty_len), is_static_(is_static) {
- }
-
- const char* GetShorty() const {
- return shorty_;
- }
-
- uint32_t GetShortyLength() const {
- return shorty_len_;
- }
-
- size_t NumArgs() const {
- // "1 +" because the first in Args is the receiver.
- // "- 1" because we don't count the return type.
- return (is_static_ ? 0 : 1) + GetShortyLength() - 1;
- }
-
- // Get the primitive type associated with the given parameter.
- Primitive::Type GetParamPrimitiveType(size_t param) const {
- CHECK_LT(param, NumArgs());
- if (is_static_) {
- param++; // 0th argument must skip return value at start of the shorty.
- } else if (param == 0) {
- return Primitive::kPrimNot;
- }
- return Primitive::GetType(shorty_[param]);
- }
-
- // Is the specified parameter a long or double, where parameter 0 is 'this' for instance methods.
- bool IsParamALongOrDouble(size_t param) const {
- Primitive::Type type = GetParamPrimitiveType(param);
- return type == Primitive::kPrimLong || type == Primitive::kPrimDouble;
- }
-
- // Is the specified parameter a reference, where parameter 0 is 'this' for instance methods.
- bool IsParamAReference(size_t param) const {
- return GetParamPrimitiveType(param) == Primitive::kPrimNot;
- }
-
- private:
- const char* const shorty_;
- const uint32_t shorty_len_;
- const bool is_static_;
-
- DISALLOW_COPY_AND_ASSIGN(ShortyHelper);
-};
-
-// Visits the arguments as saved to the stack by a Runtime::kRefAndArgs callee save frame.
-class PortableArgumentVisitor {
- public:
-// Offset to first (not the Method*) argument in a Runtime::kRefAndArgs callee save frame.
-// Size of Runtime::kRefAndArgs callee save frame.
-// Size of Method* and register parameters in out stack arguments.
-#if defined(__arm__)
-#define PORTABLE_CALLEE_SAVE_FRAME__REF_AND_ARGS__R1_OFFSET 8
-#define PORTABLE_CALLEE_SAVE_FRAME__REF_AND_ARGS__FRAME_SIZE 48
-#define PORTABLE_STACK_ARG_SKIP 0
-#elif defined(__mips__)
-#define PORTABLE_CALLEE_SAVE_FRAME__REF_AND_ARGS__R1_OFFSET 4
-#define PORTABLE_CALLEE_SAVE_FRAME__REF_AND_ARGS__FRAME_SIZE 64
-#define PORTABLE_STACK_ARG_SKIP 16
-#elif defined(__i386__)
-// For x86 there are no register arguments and the stack pointer will point directly to the called
-// method argument passed by the caller.
-#define PORTABLE_CALLEE_SAVE_FRAME__REF_AND_ARGS__R1_OFFSET 0
-#define PORTABLE_CALLEE_SAVE_FRAME__REF_AND_ARGS__FRAME_SIZE 0
-#define PORTABLE_STACK_ARG_SKIP 4
-#elif defined(__x86_64__)
-// TODO: implement and check these.
-#define PORTABLE_CALLEE_SAVE_FRAME__REF_AND_ARGS__R1_OFFSET 16
-#define PORTABLE_CALLEE_SAVE_FRAME__REF_AND_ARGS__FRAME_SIZE 96
-#define PORTABLE_STACK_ARG_SKIP 0
-#else
-// TODO: portable should be disabled for aarch64 for now.
-// #error "Unsupported architecture"
-#define PORTABLE_CALLEE_SAVE_FRAME__REF_AND_ARGS__R1_OFFSET 0
-#define PORTABLE_CALLEE_SAVE_FRAME__REF_AND_ARGS__FRAME_SIZE 0
-#define PORTABLE_STACK_ARG_SKIP 0
-#endif
-
- PortableArgumentVisitor(ShortyHelper& caller_mh, mirror::ArtMethod** sp)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) :
- caller_mh_(caller_mh),
- args_in_regs_(ComputeArgsInRegs(caller_mh)),
- num_params_(caller_mh.NumArgs()),
- reg_args_(reinterpret_cast<uint8_t*>(sp) + PORTABLE_CALLEE_SAVE_FRAME__REF_AND_ARGS__R1_OFFSET),
- stack_args_(reinterpret_cast<uint8_t*>(sp) + PORTABLE_CALLEE_SAVE_FRAME__REF_AND_ARGS__FRAME_SIZE
- + PORTABLE_STACK_ARG_SKIP),
- cur_args_(reg_args_),
- cur_arg_index_(0),
- param_index_(0) {
- }
-
- virtual ~PortableArgumentVisitor() {}
-
- virtual void Visit() = 0;
-
- bool IsParamAReference() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return caller_mh_.IsParamAReference(param_index_);
- }
-
- bool IsParamALongOrDouble() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return caller_mh_.IsParamALongOrDouble(param_index_);
- }
-
- Primitive::Type GetParamPrimitiveType() const SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- return caller_mh_.GetParamPrimitiveType(param_index_);
- }
-
- uint8_t* GetParamAddress() const {
- return cur_args_ + (cur_arg_index_ * sizeof(void*));
- }
-
- void VisitArguments() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- for (cur_arg_index_ = 0; cur_arg_index_ < args_in_regs_ && param_index_ < num_params_; ) {
-#if (defined(__arm__) || defined(__mips__))
- if (IsParamALongOrDouble() && cur_arg_index_ == 2) {
- break;
- }
-#endif
- Visit();
- cur_arg_index_ += (IsParamALongOrDouble() ? 2 : 1);
- param_index_++;
- }
- cur_args_ = stack_args_;
- cur_arg_index_ = 0;
- while (param_index_ < num_params_) {
-#if (defined(__arm__) || defined(__mips__))
- if (IsParamALongOrDouble() && cur_arg_index_ % 2 != 0) {
- cur_arg_index_++;
- }
-#endif
- Visit();
- cur_arg_index_ += (IsParamALongOrDouble() ? 2 : 1);
- param_index_++;
- }
- }
-
- private:
- static size_t ComputeArgsInRegs(ShortyHelper& mh) SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
-#if (defined(__i386__))
- UNUSED(mh);
- return 0;
-#else
- size_t args_in_regs = 0;
- size_t num_params = mh.NumArgs();
- for (size_t i = 0; i < num_params; i++) {
- args_in_regs = args_in_regs + (mh.IsParamALongOrDouble(i) ? 2 : 1);
- if (args_in_regs > 3) {
- args_in_regs = 3;
- break;
- }
- }
- return args_in_regs;
-#endif
- }
- ShortyHelper& caller_mh_;
- const size_t args_in_regs_;
- const size_t num_params_;
- uint8_t* const reg_args_;
- uint8_t* const stack_args_;
- uint8_t* cur_args_;
- size_t cur_arg_index_;
- size_t param_index_;
-};
-
-// Visits arguments on the stack placing them into the shadow frame.
-class BuildPortableShadowFrameVisitor : public PortableArgumentVisitor {
- public:
- BuildPortableShadowFrameVisitor(ShortyHelper& caller_mh, mirror::ArtMethod** sp,
- ShadowFrame& sf, size_t first_arg_reg) :
- PortableArgumentVisitor(caller_mh, sp), sf_(sf), cur_reg_(first_arg_reg) { }
- virtual void Visit() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- Primitive::Type type = GetParamPrimitiveType();
- switch (type) {
- case Primitive::kPrimLong: // Fall-through.
- case Primitive::kPrimDouble:
- sf_.SetVRegLong(cur_reg_, *reinterpret_cast<jlong*>(GetParamAddress()));
- ++cur_reg_;
- break;
- case Primitive::kPrimNot:
- sf_.SetVRegReference(cur_reg_, *reinterpret_cast<mirror::Object**>(GetParamAddress()));
- break;
- case Primitive::kPrimBoolean: // Fall-through.
- case Primitive::kPrimByte: // Fall-through.
- case Primitive::kPrimChar: // Fall-through.
- case Primitive::kPrimShort: // Fall-through.
- case Primitive::kPrimInt: // Fall-through.
- case Primitive::kPrimFloat:
- sf_.SetVReg(cur_reg_, *reinterpret_cast<jint*>(GetParamAddress()));
- break;
- case Primitive::kPrimVoid:
- LOG(FATAL) << "UNREACHABLE";
- UNREACHABLE();
- }
- ++cur_reg_;
- }
-
- private:
- ShadowFrame& sf_;
- size_t cur_reg_;
-
- DISALLOW_COPY_AND_ASSIGN(BuildPortableShadowFrameVisitor);
-};
-
-extern "C" uint64_t artPortableToInterpreterBridge(mirror::ArtMethod* method, Thread* self,
- mirror::ArtMethod** sp)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- // Ensure we don't get thread suspension until the object arguments are safely in the shadow
- // frame.
- // FinishCalleeSaveFrameSetup(self, sp, Runtime::kRefsAndArgs);
-
- if (method->IsAbstract()) {
- ThrowAbstractMethodError(method);
- return 0;
- } else {
- const char* old_cause = self->StartAssertNoThreadSuspension("Building interpreter shadow frame");
- StackHandleScope<2> hs(self);
- uint32_t shorty_len;
- const char* shorty = method->GetShorty(&shorty_len);
- ShortyHelper mh(shorty, shorty_len, method->IsStatic());
- const DexFile::CodeItem* code_item = method->GetCodeItem();
- uint16_t num_regs = code_item->registers_size_;
- void* memory = alloca(ShadowFrame::ComputeSize(num_regs));
- ShadowFrame* shadow_frame(ShadowFrame::Create(num_regs, NULL, // No last shadow coming from quick.
- method, 0, memory));
- size_t first_arg_reg = code_item->registers_size_ - code_item->ins_size_;
- BuildPortableShadowFrameVisitor shadow_frame_builder(mh, sp,
- *shadow_frame, first_arg_reg);
- shadow_frame_builder.VisitArguments();
- // Push a transition back into managed code onto the linked list in thread.
- ManagedStack fragment;
- self->PushManagedStackFragment(&fragment);
- self->PushShadowFrame(shadow_frame);
- self->EndAssertNoThreadSuspension(old_cause);
-
- if (method->IsStatic() && !method->GetDeclaringClass()->IsInitialized()) {
- // Ensure static method's class is initialized.
- Handle<mirror::Class> h_class(hs.NewHandle(method->GetDeclaringClass()));
- if (!Runtime::Current()->GetClassLinker()->EnsureInitialized(self, h_class, true, true)) {
- DCHECK(Thread::Current()->IsExceptionPending());
- self->PopManagedStackFragment(fragment);
- return 0;
- }
- }
-
- JValue result = interpreter::EnterInterpreterFromEntryPoint(self, code_item, shadow_frame);
- // Pop transition.
- self->PopManagedStackFragment(fragment);
- return result.GetJ();
- }
-}
-
-// Visits arguments on the stack placing them into the args vector, Object* arguments are converted
-// to jobjects.
-class BuildPortableArgumentVisitor : public PortableArgumentVisitor {
- public:
- BuildPortableArgumentVisitor(ShortyHelper& caller_mh, mirror::ArtMethod** sp,
- ScopedObjectAccessUnchecked& soa, std::vector<jvalue>& args) :
- PortableArgumentVisitor(caller_mh, sp), soa_(soa), args_(args) {}
-
- virtual void Visit() SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- jvalue val;
- Primitive::Type type = GetParamPrimitiveType();
- switch (type) {
- case Primitive::kPrimNot: {
- mirror::Object* obj = *reinterpret_cast<mirror::Object**>(GetParamAddress());
- val.l = soa_.AddLocalReference<jobject>(obj);
- break;
- }
- case Primitive::kPrimLong: // Fall-through.
- case Primitive::kPrimDouble:
- val.j = *reinterpret_cast<jlong*>(GetParamAddress());
- break;
- case Primitive::kPrimBoolean: // Fall-through.
- case Primitive::kPrimByte: // Fall-through.
- case Primitive::kPrimChar: // Fall-through.
- case Primitive::kPrimShort: // Fall-through.
- case Primitive::kPrimInt: // Fall-through.
- case Primitive::kPrimFloat:
- val.i = *reinterpret_cast<jint*>(GetParamAddress());
- break;
- case Primitive::kPrimVoid:
- LOG(FATAL) << "UNREACHABLE";
- UNREACHABLE();
- }
- args_.push_back(val);
- }
-
- private:
- ScopedObjectAccessUnchecked& soa_;
- std::vector<jvalue>& args_;
-
- DISALLOW_COPY_AND_ASSIGN(BuildPortableArgumentVisitor);
-};
-
-// Handler for invocation on proxy methods. On entry a frame will exist for the proxy object method
-// which is responsible for recording callee save registers. We explicitly place into jobjects the
-// incoming reference arguments (so they survive GC). We invoke the invocation handler, which is a
-// field within the proxy object, which will box the primitive arguments and deal with error cases.
-extern "C" uint64_t artPortableProxyInvokeHandler(mirror::ArtMethod* proxy_method,
- mirror::Object* receiver,
- Thread* self, mirror::ArtMethod** sp)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- // Ensure we don't get thread suspension until the object arguments are safely in jobjects.
- const char* old_cause =
- self->StartAssertNoThreadSuspension("Adding to IRT proxy object arguments");
- self->VerifyStack();
- // Start new JNI local reference state.
- JNIEnvExt* env = self->GetJniEnv();
- ScopedObjectAccessUnchecked soa(env);
- ScopedJniEnvLocalRefState env_state(env);
- // Create local ref. copies of proxy method and the receiver.
- jobject rcvr_jobj = soa.AddLocalReference<jobject>(receiver);
-
- // Placing arguments into args vector and remove the receiver.
- uint32_t shorty_len;
- const char* shorty = proxy_method->GetShorty(&shorty_len);
- ShortyHelper proxy_mh(shorty, shorty_len, false);
- std::vector<jvalue> args;
- BuildPortableArgumentVisitor local_ref_visitor(proxy_mh, sp, soa, args);
- local_ref_visitor.VisitArguments();
- args.erase(args.begin());
-
- // Convert proxy method into expected interface method.
- mirror::ArtMethod* interface_method = proxy_method->FindOverriddenMethod();
- DCHECK(interface_method != NULL);
- DCHECK(!interface_method->IsProxyMethod()) << PrettyMethod(interface_method);
- jobject interface_method_jobj = soa.AddLocalReference<jobject>(interface_method);
-
- // All naked Object*s should now be in jobjects, so its safe to go into the main invoke code
- // that performs allocations.
- self->EndAssertNoThreadSuspension(old_cause);
- JValue result = InvokeProxyInvocationHandler(soa, proxy_mh.GetShorty(),
- rcvr_jobj, interface_method_jobj, args);
- return result.GetJ();
-}
-
-// Lazily resolve a method for portable. Called by stub code.
-extern "C" const void* artPortableResolutionTrampoline(mirror::ArtMethod* called,
- mirror::Object* receiver,
- Thread* self,
- mirror::ArtMethod** called_addr)
- SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
- uint32_t dex_pc;
- mirror::ArtMethod* caller = self->GetCurrentMethod(&dex_pc);
-
- ClassLinker* class_linker = Runtime::Current()->GetClassLinker();
- InvokeType invoke_type;
- bool is_range;
- if (called->IsRuntimeMethod()) {
- const DexFile::CodeItem* code = caller->GetCodeItem();
- CHECK_LT(dex_pc, code->insns_size_in_code_units_);
- const Instruction* instr = Instruction::At(&code->insns_[dex_pc]);
- Instruction::Code instr_code = instr->Opcode();
- switch (instr_code) {
- case Instruction::INVOKE_DIRECT:
- invoke_type = kDirect;
- is_range = false;
- break;
- case Instruction::INVOKE_DIRECT_RANGE:
- invoke_type = kDirect;
- is_range = true;
- break;
- case Instruction::INVOKE_STATIC:
- invoke_type = kStatic;
- is_range = false;
- break;
- case Instruction::INVOKE_STATIC_RANGE:
- invoke_type = kStatic;
- is_range = true;
- break;
- case Instruction::INVOKE_SUPER:
- invoke_type = kSuper;
- is_range = false;
- break;
- case Instruction::INVOKE_SUPER_RANGE:
- invoke_type = kSuper;
- is_range = true;
- break;
- case Instruction::INVOKE_VIRTUAL:
- invoke_type = kVirtual;
- is_range = false;
- break;
- case Instruction::INVOKE_VIRTUAL_RANGE:
- invoke_type = kVirtual;
- is_range = true;
- break;
- case Instruction::INVOKE_INTERFACE:
- invoke_type = kInterface;
- is_range = false;
- break;
- case Instruction::INVOKE_INTERFACE_RANGE:
- invoke_type = kInterface;
- is_range = true;
- break;
- default:
- LOG(FATAL) << "Unexpected call into trampoline: " << instr->DumpString(NULL);
- // Avoid used uninitialized warnings.
- invoke_type = kDirect;
- is_range = true;
- }
- uint32_t dex_method_idx = (is_range) ? instr->VRegB_3rc() : instr->VRegB_35c();
- called = class_linker->ResolveMethod(Thread::Current(), dex_method_idx, &caller, invoke_type);
- // Incompatible class change should have been handled in resolve method.
- CHECK(!called->CheckIncompatibleClassChange(invoke_type));
- // Refine called method based on receiver.
- if (invoke_type == kVirtual) {
- called = receiver->GetClass()->FindVirtualMethodForVirtual(called);
- } else if (invoke_type == kInterface) {
- called = receiver->GetClass()->FindVirtualMethodForInterface(called);
- }
- } else {
- CHECK(called->IsStatic()) << PrettyMethod(called);
- invoke_type = kStatic;
- // Incompatible class change should have been handled in resolve method.
- CHECK(!called->CheckIncompatibleClassChange(invoke_type));
- }
- const void* code = nullptr;
- if (LIKELY(!self->IsExceptionPending())) {
- // Ensure that the called method's class is initialized.
- StackHandleScope<1> hs(self);
- Handle<mirror::Class> called_class(hs.NewHandle(called->GetDeclaringClass()));
- class_linker->EnsureInitialized(self, called_class, true, true);
- if (LIKELY(called_class->IsInitialized())) {
- code = called->GetEntryPointFromPortableCompiledCode();
- // TODO: remove this after we solve the link issue.
- if (code == nullptr) {
- bool have_portable_code;
- code = class_linker->GetPortableOatCodeFor(called, &have_portable_code);
- }
- } else if (called_class->IsInitializing()) {
- if (invoke_type == kStatic) {
- // Class is still initializing, go to oat and grab code (trampoline must be left in place
- // until class is initialized to stop races between threads).
- bool have_portable_code;
- code = class_linker->GetPortableOatCodeFor(called, &have_portable_code);
- } else {
- // No trampoline for non-static methods.
- code = called->GetEntryPointFromPortableCompiledCode();
- // TODO: remove this after we solve the link issue.
- if (code == nullptr) {
- bool have_portable_code;
- code = class_linker->GetPortableOatCodeFor(called, &have_portable_code);
- }
- }
- } else {
- DCHECK(called_class->IsErroneous());
- }
- }
- if (LIKELY(code != nullptr)) {
- // Expect class to at least be initializing.
- DCHECK(called->GetDeclaringClass()->IsInitializing());
- // Don't want infinite recursion.
- DCHECK(!class_linker->IsPortableResolutionStub(code));
- // Set up entry into main method
- *called_addr = called;
- }
- return code;
-}
-
-} // namespace art
-
-#endif // ART_RUNTIME_ENTRYPOINTS_PORTABLE_PORTABLE_ARGUMENT_VISITOR_H_
diff --git a/runtime/entrypoints/runtime_asm_entrypoints.h b/runtime/entrypoints/runtime_asm_entrypoints.h
index db36a73956..420e8db7c8 100644
--- a/runtime/entrypoints/runtime_asm_entrypoints.h
+++ b/runtime/entrypoints/runtime_asm_entrypoints.h
@@ -28,66 +28,30 @@ static inline const void* GetJniDlsymLookupStub() {
return reinterpret_cast<const void*>(art_jni_dlsym_lookup_stub);
}
-// Return the address of portable stub code for handling IMT conflicts.
-extern "C" void art_portable_imt_conflict_trampoline(mirror::ArtMethod*);
-static inline const void* GetPortableImtConflictStub() {
- return reinterpret_cast<const void*>(art_portable_imt_conflict_trampoline);
-}
-
// Return the address of quick stub code for handling IMT conflicts.
extern "C" void art_quick_imt_conflict_trampoline(mirror::ArtMethod*);
static inline const void* GetQuickImtConflictStub() {
return reinterpret_cast<const void*>(art_quick_imt_conflict_trampoline);
}
-// Return the address of portable stub code for bridging from portable code to the interpreter.
-extern "C" void art_portable_to_interpreter_bridge(mirror::ArtMethod*);
-static inline const void* GetPortableToInterpreterBridge() {
- return reinterpret_cast<const void*>(art_portable_to_interpreter_bridge);
-}
-
// Return the address of quick stub code for bridging from quick code to the interpreter.
extern "C" void art_quick_to_interpreter_bridge(mirror::ArtMethod*);
static inline const void* GetQuickToInterpreterBridge() {
return reinterpret_cast<const void*>(art_quick_to_interpreter_bridge);
}
-// Return the address of portable stub code for bridging from portable code to quick.
-static inline const void* GetPortableToQuickBridge() {
- // TODO: portable to quick bridge. Bug: 8196384
- return GetPortableToInterpreterBridge();
-}
-
-// Return the address of quick stub code for bridging from quick code to portable.
-static inline const void* GetQuickToPortableBridge() {
- // TODO: quick to portable bridge. Bug: 8196384
- return GetQuickToInterpreterBridge();
-}
-
// Return the address of quick stub code for handling JNI calls.
extern "C" void art_quick_generic_jni_trampoline(mirror::ArtMethod*);
static inline const void* GetQuickGenericJniStub() {
return reinterpret_cast<const void*>(art_quick_generic_jni_trampoline);
}
-// Return the address of portable stub code for handling transitions into the proxy invoke handler.
-extern "C" void art_portable_proxy_invoke_handler();
-static inline const void* GetPortableProxyInvokeHandler() {
- return reinterpret_cast<const void*>(art_portable_proxy_invoke_handler);
-}
-
// Return the address of quick stub code for handling transitions into the proxy invoke handler.
extern "C" void art_quick_proxy_invoke_handler();
static inline const void* GetQuickProxyInvokeHandler() {
return reinterpret_cast<const void*>(art_quick_proxy_invoke_handler);
}
-// Return the address of portable stub code for resolving a method at first call.
-extern "C" void art_portable_resolution_trampoline(mirror::ArtMethod*);
-static inline const void* GetPortableResolutionStub() {
- return reinterpret_cast<const void*>(art_portable_resolution_trampoline);
-}
-
// Return the address of quick stub code for resolving a method at first call.
extern "C" void art_quick_resolution_trampoline(mirror::ArtMethod*);
static inline const void* GetQuickResolutionStub() {