summaryrefslogtreecommitdiffstats
path: root/runtime/arch
diff options
context:
space:
mode:
authorFred Shih <ffred@google.com>2014-07-16 18:38:08 -0700
committerFred Shih <ffred@google.com>2014-08-25 11:16:53 -0700
commit37f05ef45e0393de812d51261dc293240c17294d (patch)
tree7c7793862efa52e1deb42babbdcb652c245ab941 /runtime/arch
parente25826e28ea65d9c1aa23f84788a091c677b20c7 (diff)
downloadandroid_art-37f05ef45e0393de812d51261dc293240c17294d.tar.gz
android_art-37f05ef45e0393de812d51261dc293240c17294d.tar.bz2
android_art-37f05ef45e0393de812d51261dc293240c17294d.zip
Reduced memory usage of primitive fields smaller than 4-bytes
Reduced memory used by byte and boolean fields from 4 bytes down to a single byte and shorts and chars down to two bytes. Fields are now arranged as Reference followed by decreasing component sizes, with fields shuffled forward as needed. Bug: 8135266 Change-Id: I65eaf31ed27e5bd5ba0c7d4606454b720b074752
Diffstat (limited to 'runtime/arch')
-rw-r--r--runtime/arch/arm/entrypoints_init_arm.cc24
-rw-r--r--runtime/arch/arm/quick_entrypoints_arm.S255
-rw-r--r--runtime/arch/arm64/entrypoints_init_arm64.cc24
-rw-r--r--runtime/arch/arm64/quick_entrypoints_arm64.S12
-rw-r--r--runtime/arch/mips/entrypoints_init_mips.cc24
-rw-r--r--runtime/arch/mips/quick_entrypoints_mips.S167
-rw-r--r--runtime/arch/stub_test.cc349
-rw-r--r--runtime/arch/x86/entrypoints_init_x86.cc24
-rw-r--r--runtime/arch/x86/quick_entrypoints_x86.S171
-rw-r--r--runtime/arch/x86_64/entrypoints_init_x86_64.cc24
-rw-r--r--runtime/arch/x86_64/quick_entrypoints_x86_64.S12
11 files changed, 864 insertions, 222 deletions
diff --git a/runtime/arch/arm/entrypoints_init_arm.cc b/runtime/arch/arm/entrypoints_init_arm.cc
index 8c6afd66bd..38a88c574c 100644
--- a/runtime/arch/arm/entrypoints_init_arm.cc
+++ b/runtime/arch/arm/entrypoints_init_arm.cc
@@ -48,12 +48,24 @@ extern "C" void* art_quick_initialize_type_and_verify_access(uint32_t, void*);
extern "C" void* art_quick_resolve_string(void*, uint32_t);
// Field entrypoints.
+extern "C" int art_quick_set8_instance(uint32_t, void*, int8_t);
+extern "C" int art_quick_set8_static(uint32_t, int8_t);
+extern "C" int art_quick_set16_instance(uint32_t, void*, int16_t);
+extern "C" int art_quick_set16_static(uint32_t, int16_t);
extern "C" int art_quick_set32_instance(uint32_t, void*, int32_t);
extern "C" int art_quick_set32_static(uint32_t, int32_t);
extern "C" int art_quick_set64_instance(uint32_t, void*, int64_t);
extern "C" int art_quick_set64_static(uint32_t, int64_t);
extern "C" int art_quick_set_obj_instance(uint32_t, void*, void*);
extern "C" int art_quick_set_obj_static(uint32_t, void*);
+extern "C" int8_t art_quick_get_byte_instance(uint32_t, void*);
+extern "C" uint8_t art_quick_get_boolean_instance(uint32_t, void*);
+extern "C" int8_t art_quick_get_byte_static(uint32_t);
+extern "C" uint8_t art_quick_get_boolean_static(uint32_t);
+extern "C" int16_t art_quick_get_short_instance(uint32_t, void*);
+extern "C" uint16_t art_quick_get_char_instance(uint32_t, void*);
+extern "C" int16_t art_quick_get_short_static(uint32_t);
+extern "C" uint16_t art_quick_get_char_static(uint32_t);
extern "C" int32_t art_quick_get32_instance(uint32_t, void*);
extern "C" int32_t art_quick_get32_static(uint32_t);
extern "C" int64_t art_quick_get64_instance(uint32_t, void*);
@@ -154,15 +166,27 @@ void InitEntryPoints(InterpreterEntryPoints* ipoints, JniEntryPoints* jpoints,
qpoints->pResolveString = art_quick_resolve_string;
// Field
+ qpoints->pSet8Instance = art_quick_set8_instance;
+ qpoints->pSet8Static = art_quick_set8_static;
+ qpoints->pSet16Instance = art_quick_set16_instance;
+ qpoints->pSet16Static = art_quick_set16_static;
qpoints->pSet32Instance = art_quick_set32_instance;
qpoints->pSet32Static = art_quick_set32_static;
qpoints->pSet64Instance = art_quick_set64_instance;
qpoints->pSet64Static = art_quick_set64_static;
qpoints->pSetObjInstance = art_quick_set_obj_instance;
qpoints->pSetObjStatic = art_quick_set_obj_static;
+ qpoints->pGetByteInstance = art_quick_get_byte_instance;
+ qpoints->pGetBooleanInstance = art_quick_get_boolean_instance;
+ qpoints->pGetShortInstance = art_quick_get_short_instance;
+ qpoints->pGetCharInstance = art_quick_get_char_instance;
qpoints->pGet32Instance = art_quick_get32_instance;
qpoints->pGet64Instance = art_quick_get64_instance;
qpoints->pGetObjInstance = art_quick_get_obj_instance;
+ qpoints->pGetByteStatic = art_quick_get_byte_static;
+ qpoints->pGetBooleanStatic = art_quick_get_boolean_static;
+ qpoints->pGetShortStatic = art_quick_get_short_static;
+ qpoints->pGetCharStatic = art_quick_get_char_static;
qpoints->pGet32Static = art_quick_get32_static;
qpoints->pGet64Static = art_quick_get64_static;
qpoints->pGetObjStatic = art_quick_get_obj_static;
diff --git a/runtime/arch/arm/quick_entrypoints_arm.S b/runtime/arch/arm/quick_entrypoints_arm.S
index 1b30c9cca2..51bcd3c654 100644
--- a/runtime/arch/arm/quick_entrypoints_arm.S
+++ b/runtime/arch/arm/quick_entrypoints_arm.S
@@ -203,6 +203,77 @@ ENTRY \c_name
END \c_name
.endm
+.macro RETURN_OR_DELIVER_PENDING_EXCEPTION_REG reg
+ ldr \reg, [r9, #THREAD_EXCEPTION_OFFSET] // Get exception field.
+ cbnz \reg, 1f
+ bx lr
+1:
+ DELIVER_PENDING_EXCEPTION
+.endm
+
+.macro RETURN_OR_DELIVER_PENDING_EXCEPTION_R1
+ RETURN_OR_DELIVER_PENDING_EXCEPTION_REG r1
+.endm
+
+.macro RETURN_IF_RESULT_IS_ZERO_OR_DELIVER
+ RETURN_IF_RESULT_IS_ZERO
+ DELIVER_PENDING_EXCEPTION
+.endm
+
+// Macros taking opportunity of code similarities for downcalls with referrer for non-wide fields.
+.macro ONE_ARG_REF_DOWNCALL name, entrypoint, return
+ .extern \entrypoint
+ENTRY \name
+ SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
+ ldr r1, [sp, #32] @ pass referrer
+ mov r2, r9 @ pass Thread::Current
+ mov r3, sp @ pass SP
+ bl \entrypoint @ (uint32_t field_idx, const Method* referrer, Thread*, SP)
+ RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
+ \return
+END \name
+.endm
+
+.macro TWO_ARG_REF_DOWNCALL name, entrypoint, return
+ .extern \entrypoint
+ENTRY \name
+ SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
+ ldr r2, [sp, #32] @ pass referrer
+ mov r3, r9 @ pass Thread::Current
+ mov r12, sp
+ str r12, [sp, #-16]! @ expand the frame and pass SP
+ .pad #16
+ .cfi_adjust_cfa_offset 16
+ bl \entrypoint @ (field_idx, Object*, referrer, Thread*, SP)
+ add sp, #16 @ strip the extra frame
+ .cfi_adjust_cfa_offset -16
+ RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
+ \return
+END \name
+.endm
+
+.macro THREE_ARG_REF_DOWNCALL name, entrypoint, return
+ .extern \entrypoint
+ENTRY \name
+ SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
+ ldr r3, [sp, #32] @ pass referrer
+ mov r12, sp @ save SP
+ sub sp, #8 @ grow frame for alignment with stack args
+ .pad #8
+ .cfi_adjust_cfa_offset 8
+ push {r9, r12} @ pass Thread::Current and SP
+ .save {r9, r12}
+ .cfi_adjust_cfa_offset 8
+ .cfi_rel_offset r9, 0
+ .cfi_rel_offset r12, 4
+ bl \entrypoint @ (field_idx, Object*, new_val, referrer, Thread*, SP)
+ add sp, #16 @ release out args
+ .cfi_adjust_cfa_offset -16
+ RESTORE_REF_ONLY_CALLEE_SAVE_FRAME @ TODO: we can clearly save an add here
+ \return
+END \name
+.endm
+
/*
* Called by managed code, saves callee saves and then calls artThrowException
* that will place a mock Method* at the bottom of the stack. Arg1 holds the exception.
@@ -601,23 +672,14 @@ ENTRY art_quick_initialize_type_and_verify_access
END art_quick_initialize_type_and_verify_access
/*
- * Called by managed code to resolve a static field and load a 32-bit primitive value.
+ * Called by managed code to resolve a static field and load a non-wide value.
*/
- .extern artGet32StaticFromCode
-ENTRY art_quick_get32_static
- SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
- ldr r1, [sp, #32] @ pass referrer
- mov r2, r9 @ pass Thread::Current
- mov r3, sp @ pass SP
- bl artGet32StaticFromCode @ (uint32_t field_idx, const Method* referrer, Thread*, SP)
- ldr r1, [r9, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_
- RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
- cbnz r1, 1f @ success if no exception pending
- bx lr @ return on success
-1:
- DELIVER_PENDING_EXCEPTION
-END art_quick_get32_static
-
+ONE_ARG_REF_DOWNCALL art_quick_get_byte_static, artGetByteStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1
+ONE_ARG_REF_DOWNCALL art_quick_get_boolean_static, artGetBooleanStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1
+ONE_ARG_REF_DOWNCALL art_quick_get_short_static, artGetShortStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1
+ONE_ARG_REF_DOWNCALL art_quick_get_char_static, artGetCharStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1
+ONE_ARG_REF_DOWNCALL art_quick_get32_static, artGet32StaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1
+ONE_ARG_REF_DOWNCALL art_quick_get_obj_static, artGetObjStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1
/*
* Called by managed code to resolve a static field and load a 64-bit primitive value.
*/
@@ -637,43 +699,14 @@ ENTRY art_quick_get64_static
END art_quick_get64_static
/*
- * Called by managed code to resolve a static field and load an object reference.
+ * Called by managed code to resolve an instance field and load a non-wide value.
*/
- .extern artGetObjStaticFromCode
-ENTRY art_quick_get_obj_static
- SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
- ldr r1, [sp, #32] @ pass referrer
- mov r2, r9 @ pass Thread::Current
- mov r3, sp @ pass SP
- bl artGetObjStaticFromCode @ (uint32_t field_idx, const Method* referrer, Thread*, SP)
- ldr r1, [r9, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_
- RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
- cbnz r1, 1f @ success if no exception pending
- bx lr @ return on success
-1:
- DELIVER_PENDING_EXCEPTION
-END art_quick_get_obj_static
-
- /*
- * Called by managed code to resolve an instance field and load a 32-bit primitive value.
- */
- .extern artGet32InstanceFromCode
-ENTRY art_quick_get32_instance
- SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
- ldr r2, [sp, #32] @ pass referrer
- mov r3, r9 @ pass Thread::Current
- mov r12, sp
- str r12, [sp, #-16]! @ expand the frame and pass SP
- bl artGet32InstanceFromCode @ (field_idx, Object*, referrer, Thread*, SP)
- add sp, #16 @ strip the extra frame
- ldr r1, [r9, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_
- RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
- cbnz r1, 1f @ success if no exception pending
- bx lr @ return on success
-1:
- DELIVER_PENDING_EXCEPTION
-END art_quick_get32_instance
-
+TWO_ARG_REF_DOWNCALL art_quick_get_byte_instance, artGetByteInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1
+TWO_ARG_REF_DOWNCALL art_quick_get_boolean_instance, artGetBooleanInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1
+TWO_ARG_REF_DOWNCALL art_quick_get_short_instance, artGetShortInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1
+TWO_ARG_REF_DOWNCALL art_quick_get_char_instance, artGetCharInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1
+TWO_ARG_REF_DOWNCALL art_quick_get32_instance, artGet32InstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1
+TWO_ARG_REF_DOWNCALL art_quick_get_obj_instance, artGetObjInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_R1
/*
* Called by managed code to resolve an instance field and load a 64-bit primitive value.
*/
@@ -698,48 +731,12 @@ ENTRY art_quick_get64_instance
END art_quick_get64_instance
/*
- * Called by managed code to resolve an instance field and load an object reference.
- */
- .extern artGetObjInstanceFromCode
-ENTRY art_quick_get_obj_instance
- SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
- ldr r2, [sp, #32] @ pass referrer
- mov r3, r9 @ pass Thread::Current
- mov r12, sp
- str r12, [sp, #-16]! @ expand the frame and pass SP
- .pad #16
- .cfi_adjust_cfa_offset 16
- bl artGetObjInstanceFromCode @ (field_idx, Object*, referrer, Thread*, SP)
- add sp, #16 @ strip the extra frame
- .cfi_adjust_cfa_offset -16
- ldr r1, [r9, #THREAD_EXCEPTION_OFFSET] @ load Thread::Current()->exception_
- RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
- cbnz r1, 1f @ success if no exception pending
- bx lr @ return on success
-1:
- DELIVER_PENDING_EXCEPTION
-END art_quick_get_obj_instance
-
- /*
- * Called by managed code to resolve a static field and store a 32-bit primitive value.
+ * Called by managed code to resolve a static field and store a non-wide value.
*/
- .extern artSet32StaticFromCode
-ENTRY art_quick_set32_static
- SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
- ldr r2, [sp, #32] @ pass referrer
- mov r3, r9 @ pass Thread::Current
- mov r12, sp
- str r12, [sp, #-16]! @ expand the frame and pass SP
- .pad #16
- .cfi_adjust_cfa_offset 16
- bl artSet32StaticFromCode @ (field_idx, new_val, referrer, Thread*, SP)
- add sp, #16 @ strip the extra frame
- .cfi_adjust_cfa_offset -16
- RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
- RETURN_IF_RESULT_IS_ZERO
- DELIVER_PENDING_EXCEPTION
-END art_quick_set32_static
-
+TWO_ARG_REF_DOWNCALL art_quick_set8_static, artSet8StaticFromCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER
+TWO_ARG_REF_DOWNCALL art_quick_set16_static, artSet16StaticFromCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER
+TWO_ARG_REF_DOWNCALL art_quick_set32_static, artSet32StaticFromCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER
+TWO_ARG_REF_DOWNCALL art_quick_set_obj_static, artSetObjStaticFromCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER
/*
* Called by managed code to resolve a static field and store a 64-bit primitive value.
* On entry r0 holds field index, r1:r2 hold new_val
@@ -767,53 +764,16 @@ ENTRY art_quick_set64_static
END art_quick_set64_static
/*
- * Called by managed code to resolve a static field and store an object reference.
- */
- .extern artSetObjStaticFromCode
-ENTRY art_quick_set_obj_static
- SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
- ldr r2, [sp, #32] @ pass referrer
- mov r3, r9 @ pass Thread::Current
- mov r12, sp
- str r12, [sp, #-16]! @ expand the frame and pass SP
- .pad #16
- .cfi_adjust_cfa_offset 16
- bl artSetObjStaticFromCode @ (field_idx, new_val, referrer, Thread*, SP)
- add sp, #16 @ strip the extra frame
- .cfi_adjust_cfa_offset -16
- RESTORE_REF_ONLY_CALLEE_SAVE_FRAME
- RETURN_IF_RESULT_IS_ZERO
- DELIVER_PENDING_EXCEPTION
-END art_quick_set_obj_static
-
- /*
- * Called by managed code to resolve an instance field and store a 32-bit primitive value.
+ * Called by managed code to resolve an instance field and store a non-wide value.
*/
- .extern artSet32InstanceFromCode
-ENTRY art_quick_set32_instance
- SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
- ldr r3, [sp, #32] @ pass referrer
- mov r12, sp @ save SP
- sub sp, #8 @ grow frame for alignment with stack args
- .pad #8
- .cfi_adjust_cfa_offset 8
- push {r9, r12} @ pass Thread::Current and SP
- .save {r9, r12}
- .cfi_adjust_cfa_offset 8
- .cfi_rel_offset r9, 0
- .cfi_rel_offset r12, 4
- bl artSet32InstanceFromCode @ (field_idx, Object*, new_val, referrer, Thread*, SP)
- add sp, #16 @ release out args
- .cfi_adjust_cfa_offset -16
- RESTORE_REF_ONLY_CALLEE_SAVE_FRAME @ TODO: we can clearly save an add here
- RETURN_IF_RESULT_IS_ZERO
- DELIVER_PENDING_EXCEPTION
-END art_quick_set32_instance
-
+THREE_ARG_REF_DOWNCALL art_quick_set8_instance, artSet8InstanceFromCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER
+THREE_ARG_REF_DOWNCALL art_quick_set16_instance, artSet16InstanceFromCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER
+THREE_ARG_REF_DOWNCALL art_quick_set32_instance, artSet32InstanceFromCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER
+THREE_ARG_REF_DOWNCALL art_quick_set_obj_instance, artSetObjInstanceFromCode, RETURN_IF_RESULT_IS_ZERO_OR_DELIVER
/*
* Called by managed code to resolve an instance field and store a 64-bit primitive value.
*/
- .extern artSet32InstanceFromCode
+ .extern artSet64InstanceFromCode
ENTRY art_quick_set64_instance
SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
mov r12, sp @ save SP
@@ -833,29 +793,6 @@ ENTRY art_quick_set64_instance
END art_quick_set64_instance
/*
- * Called by managed code to resolve an instance field and store an object reference.
- */
- .extern artSetObjInstanceFromCode
-ENTRY art_quick_set_obj_instance
- SETUP_REF_ONLY_CALLEE_SAVE_FRAME @ save callee saves in case of GC
- ldr r3, [sp, #32] @ pass referrer
- mov r12, sp @ save SP
- sub sp, #8 @ grow frame for alignment with stack args
- .pad #8
- .cfi_adjust_cfa_offset 8
- push {r9, r12} @ pass Thread::Current and SP
- .save {r9, r12}
- .cfi_adjust_cfa_offset 8
- .cfi_rel_offset r9, 0
- bl artSetObjInstanceFromCode @ (field_idx, Object*, new_val, referrer, Thread*, SP)
- add sp, #16 @ release out args
- .cfi_adjust_cfa_offset -16
- RESTORE_REF_ONLY_CALLEE_SAVE_FRAME @ TODO: we can clearly save an add here
- RETURN_IF_RESULT_IS_ZERO
- DELIVER_PENDING_EXCEPTION
-END art_quick_set_obj_instance
-
- /*
* Entry from managed code to resolve a string, this stub will allocate a String and deliver an
* exception on error. On success the String is returned. R0 holds the referring method,
* R1 holds the string index. The fast path check for hit in strings cache has already been
diff --git a/runtime/arch/arm64/entrypoints_init_arm64.cc b/runtime/arch/arm64/entrypoints_init_arm64.cc
index 0c33d9ce83..70e93b3051 100644
--- a/runtime/arch/arm64/entrypoints_init_arm64.cc
+++ b/runtime/arch/arm64/entrypoints_init_arm64.cc
@@ -47,12 +47,24 @@ extern "C" void* art_quick_initialize_type_and_verify_access(uint32_t, void*);
extern "C" void* art_quick_resolve_string(void*, uint32_t);
// Field entrypoints.
+extern "C" int art_quick_set8_instance(uint32_t, void*, int8_t);
+extern "C" int art_quick_set8_static(uint32_t, int8_t);
+extern "C" int art_quick_set16_instance(uint32_t, void*, int16_t);
+extern "C" int art_quick_set16_static(uint32_t, int16_t);
extern "C" int art_quick_set32_instance(uint32_t, void*, int32_t);
extern "C" int art_quick_set32_static(uint32_t, int32_t);
extern "C" int art_quick_set64_instance(uint32_t, void*, int64_t);
extern "C" int art_quick_set64_static(uint32_t, int64_t);
extern "C" int art_quick_set_obj_instance(uint32_t, void*, void*);
extern "C" int art_quick_set_obj_static(uint32_t, void*);
+extern "C" uint8_t art_quick_get_boolean_instance(uint32_t, void*);
+extern "C" int8_t art_quick_get_byte_instance(uint32_t, void*);
+extern "C" uint8_t art_quick_get_boolean_static(uint32_t);
+extern "C" int8_t art_quick_get_byte_static(uint32_t);
+extern "C" uint16_t art_quick_get_char_instance(uint32_t, void*);
+extern "C" int16_t art_quick_get_short_instance(uint32_t, void*);
+extern "C" uint16_t art_quick_get_char_static(uint32_t);
+extern "C" int16_t art_quick_get_short_static(uint32_t);
extern "C" int32_t art_quick_get32_instance(uint32_t, void*);
extern "C" int32_t art_quick_get32_static(uint32_t);
extern "C" int64_t art_quick_get64_instance(uint32_t, void*);
@@ -136,15 +148,27 @@ void InitEntryPoints(InterpreterEntryPoints* ipoints, JniEntryPoints* jpoints,
qpoints->pResolveString = art_quick_resolve_string;
// Field
+ qpoints->pSet8Instance = art_quick_set8_instance;
+ qpoints->pSet8Static = art_quick_set8_static;
+ qpoints->pSet16Instance = art_quick_set16_instance;
+ qpoints->pSet16Static = art_quick_set16_static;
qpoints->pSet32Instance = art_quick_set32_instance;
qpoints->pSet32Static = art_quick_set32_static;
qpoints->pSet64Instance = art_quick_set64_instance;
qpoints->pSet64Static = art_quick_set64_static;
qpoints->pSetObjInstance = art_quick_set_obj_instance;
qpoints->pSetObjStatic = art_quick_set_obj_static;
+ qpoints->pGetBooleanInstance = art_quick_get_boolean_instance;
+ qpoints->pGetByteInstance = art_quick_get_byte_instance;
+ qpoints->pGetCharInstance = art_quick_get_char_instance;
+ qpoints->pGetShortInstance = art_quick_get_short_instance;
qpoints->pGet32Instance = art_quick_get32_instance;
qpoints->pGet64Instance = art_quick_get64_instance;
qpoints->pGetObjInstance = art_quick_get_obj_instance;
+ qpoints->pGetBooleanStatic = art_quick_get_boolean_static;
+ qpoints->pGetByteStatic = art_quick_get_byte_static;
+ qpoints->pGetCharStatic = art_quick_get_char_static;
+ qpoints->pGetShortStatic = art_quick_get_short_static;
qpoints->pGet32Static = art_quick_get32_static;
qpoints->pGet64Static = art_quick_get64_static;
qpoints->pGetObjStatic = art_quick_get_obj_static;
diff --git a/runtime/arch/arm64/quick_entrypoints_arm64.S b/runtime/arch/arm64/quick_entrypoints_arm64.S
index 2a19e27b04..606816a181 100644
--- a/runtime/arch/arm64/quick_entrypoints_arm64.S
+++ b/runtime/arch/arm64/quick_entrypoints_arm64.S
@@ -1266,17 +1266,29 @@ TWO_ARG_DOWNCALL art_quick_initialize_static_storage, artInitializeStaticStorage
TWO_ARG_DOWNCALL art_quick_initialize_type, artInitializeTypeFromCode, RETURN_IF_RESULT_IS_NON_ZERO
TWO_ARG_DOWNCALL art_quick_initialize_type_and_verify_access, artInitializeTypeAndVerifyAccessFromCode, RETURN_IF_RESULT_IS_NON_ZERO
+ONE_ARG_REF_DOWNCALL art_quick_get_boolean_static, artGetBooleanStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1
+ONE_ARG_REF_DOWNCALL art_quick_get_byte_static, artGetByteStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1
+ONE_ARG_REF_DOWNCALL art_quick_get_char_static, artGetCharStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1
+ONE_ARG_REF_DOWNCALL art_quick_get_short_static, artGetShortStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1
ONE_ARG_REF_DOWNCALL art_quick_get32_static, artGet32StaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1
ONE_ARG_REF_DOWNCALL art_quick_get64_static, artGet64StaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1
ONE_ARG_REF_DOWNCALL art_quick_get_obj_static, artGetObjStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1
+TWO_ARG_REF_DOWNCALL art_quick_get_boolean_instance, artGetBooleanInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1
+TWO_ARG_REF_DOWNCALL art_quick_get_byte_instance, artGetByteInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1
+TWO_ARG_REF_DOWNCALL art_quick_get_char_instance, artGetCharInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1
+TWO_ARG_REF_DOWNCALL art_quick_get_short_instance, artGetShortInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1
TWO_ARG_REF_DOWNCALL art_quick_get32_instance, artGet32InstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1
TWO_ARG_REF_DOWNCALL art_quick_get64_instance, artGet64InstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1
TWO_ARG_REF_DOWNCALL art_quick_get_obj_instance, artGetObjInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION_X1
+TWO_ARG_REF_DOWNCALL art_quick_set8_static, artSet8StaticFromCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER
+TWO_ARG_REF_DOWNCALL art_quick_set16_static, artSet16StaticFromCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER
TWO_ARG_REF_DOWNCALL art_quick_set32_static, artSet32StaticFromCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER
TWO_ARG_REF_DOWNCALL art_quick_set_obj_static, artSetObjStaticFromCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER
+THREE_ARG_REF_DOWNCALL art_quick_set8_instance, artSet8InstanceFromCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER
+THREE_ARG_REF_DOWNCALL art_quick_set16_instance, artSet16InstanceFromCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER
THREE_ARG_REF_DOWNCALL art_quick_set32_instance, artSet32InstanceFromCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER
THREE_ARG_DOWNCALL art_quick_set64_instance, artSet64InstanceFromCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER
THREE_ARG_REF_DOWNCALL art_quick_set_obj_instance, artSetObjInstanceFromCode, RETURN_IF_W0_IS_ZERO_OR_DELIVER
diff --git a/runtime/arch/mips/entrypoints_init_mips.cc b/runtime/arch/mips/entrypoints_init_mips.cc
index d3e7d5e904..25e911d765 100644
--- a/runtime/arch/mips/entrypoints_init_mips.cc
+++ b/runtime/arch/mips/entrypoints_init_mips.cc
@@ -49,12 +49,24 @@ extern "C" void* art_quick_initialize_type_and_verify_access(uint32_t, void*);
extern "C" void* art_quick_resolve_string(void*, uint32_t);
// Field entrypoints.
+extern "C" int art_quick_set8_instance(uint32_t, void*, int8_t);
+extern "C" int art_quick_set8_static(uint32_t, int8_t);
+extern "C" int art_quick_set16_instance(uint32_t, void*, int16_t);
+extern "C" int art_quick_set16_static(uint32_t, int16_t);
extern "C" int art_quick_set32_instance(uint32_t, void*, int32_t);
extern "C" int art_quick_set32_static(uint32_t, int32_t);
extern "C" int art_quick_set64_instance(uint32_t, void*, int64_t);
extern "C" int art_quick_set64_static(uint32_t, int64_t);
extern "C" int art_quick_set_obj_instance(uint32_t, void*, void*);
extern "C" int art_quick_set_obj_static(uint32_t, void*);
+extern "C" uint8_t art_quick_get_boolean_instance(uint32_t, void*);
+extern "C" int8_t art_quick_get_byte_instance(uint32_t, void*);
+extern "C" uint8_t art_quick_get_boolean_static(uint32_t);
+extern "C" int8_t art_quick_get_byte_static(uint32_t);
+extern "C" uint16_t art_quick_get_char_instance(uint32_t, void*);
+extern "C" int16_t art_quick_get_short_instance(uint32_t, void*);
+extern "C" uint16_t art_quick_get_char_static(uint32_t);
+extern "C" int16_t art_quick_get_short_static(uint32_t);
extern "C" int32_t art_quick_get32_instance(uint32_t, void*);
extern "C" int32_t art_quick_get32_static(uint32_t);
extern "C" int64_t art_quick_get64_instance(uint32_t, void*);
@@ -159,15 +171,27 @@ void InitEntryPoints(InterpreterEntryPoints* ipoints, JniEntryPoints* jpoints,
qpoints->pResolveString = art_quick_resolve_string;
// Field
+ qpoints->pSet8Instance = art_quick_set8_instance;
+ qpoints->pSet8Static = art_quick_set8_static;
+ qpoints->pSet16Instance = art_quick_set16_instance;
+ qpoints->pSet16Static = art_quick_set16_static;
qpoints->pSet32Instance = art_quick_set32_instance;
qpoints->pSet32Static = art_quick_set32_static;
qpoints->pSet64Instance = art_quick_set64_instance;
qpoints->pSet64Static = art_quick_set64_static;
qpoints->pSetObjInstance = art_quick_set_obj_instance;
qpoints->pSetObjStatic = art_quick_set_obj_static;
+ qpoints->pGetBooleanInstance = art_quick_get_boolean_instance;
+ qpoints->pGetByteInstance = art_quick_get_byte_instance;
+ qpoints->pGetCharInstance = art_quick_get_char_instance;
+ qpoints->pGetShortInstance = art_quick_get_short_instance;
qpoints->pGet32Instance = art_quick_get32_instance;
qpoints->pGet64Instance = art_quick_get64_instance;
qpoints->pGetObjInstance = art_quick_get_obj_instance;
+ qpoints->pGetBooleanStatic = art_quick_get_boolean_static;
+ qpoints->pGetByteStatic = art_quick_get_byte_static;
+ qpoints->pGetCharStatic = art_quick_get_char_static;
+ qpoints->pGetShortStatic = art_quick_get_short_static;
qpoints->pGet32Static = art_quick_get32_static;
qpoints->pGet64Static = art_quick_get64_static;
qpoints->pGetObjStatic = art_quick_get_obj_static;
diff --git a/runtime/arch/mips/quick_entrypoints_mips.S b/runtime/arch/mips/quick_entrypoints_mips.S
index 8786222250..9e9e5236af 100644
--- a/runtime/arch/mips/quick_entrypoints_mips.S
+++ b/runtime/arch/mips/quick_entrypoints_mips.S
@@ -739,6 +739,59 @@ ENTRY art_quick_initialize_type_and_verify_access
move $a3, $sp # pass $sp
RETURN_IF_RESULT_IS_NON_ZERO
END art_quick_initialize_type_and_verify_access
+ /*
+ * Called by managed code to resolve a static field and load a boolean primitive value.
+ */
+ .extern artGetBooleanStaticFromCode
+ENTRY art_quick_get_boolean_static
+ GENERATE_GLOBAL_POINTER
+ SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
+ lw $a1, 64($sp) # pass referrer's Method*
+ move $a2, rSELF # pass Thread::Current
+ jal artGetBooleanStaticFromCode # (uint32_t field_idx, const Method* referrer, Thread*, $sp)
+ move $a3, $sp # pass $sp
+ RETURN_IF_NO_EXCEPTION
+END art_quick_get_boolean_static
+ /*
+ * Called by managed code to resolve a static field and load a byte primitive value.
+ */
+ .extern artGetByteStaticFromCode
+ENTRY art_quick_get_byte_static
+ GENERATE_GLOBAL_POINTER
+ SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
+ lw $a1, 64($sp) # pass referrer's Method*
+ move $a2, rSELF # pass Thread::Current
+ jal artGetByteStaticFromCode # (uint32_t field_idx, const Method* referrer, Thread*, $sp)
+ move $a3, $sp # pass $sp
+ RETURN_IF_NO_EXCEPTION
+END art_quick_get_byte_static
+
+ /*
+ * Called by managed code to resolve a static field and load a char primitive value.
+ */
+ .extern artGetCharStaticFromCode
+ENTRY art_quick_get_char_static
+ GENERATE_GLOBAL_POINTER
+ SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
+ lw $a1, 64($sp) # pass referrer's Method*
+ move $a2, rSELF # pass Thread::Current
+ jal artGetCharStaticFromCode # (uint32_t field_idx, const Method* referrer, Thread*, $sp)
+ move $a3, $sp # pass $sp
+ RETURN_IF_NO_EXCEPTION
+END art_quick_get_char_static
+ /*
+ * Called by managed code to resolve a static field and load a short primitive value.
+ */
+ .extern artGetShortStaticFromCode
+ENTRY art_quick_get_short_static
+ GENERATE_GLOBAL_POINTER
+ SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
+ lw $a1, 64($sp) # pass referrer's Method*
+ move $a2, rSELF # pass Thread::Current
+ jal artGetShortStaticFromCode # (uint32_t field_idx, const Method* referrer, Thread*, $sp)
+ move $a3, $sp # pass $sp
+ RETURN_IF_NO_EXCEPTION
+END art_quick_get_short_static
/*
* Called by managed code to resolve a static field and load a 32-bit primitive value.
@@ -783,6 +836,60 @@ ENTRY art_quick_get_obj_static
END art_quick_get_obj_static
/*
+ * Called by managed code to resolve an instance field and load a boolean primitive value.
+ */
+ .extern artGetBooleanInstanceFromCode
+ENTRY art_quick_get_boolean_instance
+ GENERATE_GLOBAL_POINTER
+ SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
+ lw $a2, 64($sp) # pass referrer's Method*
+ move $a3, rSELF # pass Thread::Current
+ jal artGetBooleanInstanceFromCode # (field_idx, Object*, referrer, Thread*, $sp)
+ sw $sp, 16($sp) # pass $sp
+ RETURN_IF_NO_EXCEPTION
+END art_quick_get_boolean_instance
+ /*
+ * Called by managed code to resolve an instance field and load a byte primitive value.
+ */
+ .extern artGetByteInstanceFromCode
+ENTRY art_quick_get_byte_instance
+ GENERATE_GLOBAL_POINTER
+ SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
+ lw $a2, 64($sp) # pass referrer's Method*
+ move $a3, rSELF # pass Thread::Current
+ jal artGetByteInstanceFromCode # (field_idx, Object*, referrer, Thread*, $sp)
+ sw $sp, 16($sp) # pass $sp
+ RETURN_IF_NO_EXCEPTION
+END art_quick_get_byte_instance
+
+ /*
+ * Called by managed code to resolve an instance field and load a char primitive value.
+ */
+ .extern artGetCharInstanceFromCode
+ENTRY art_quick_get_char_instance
+ GENERATE_GLOBAL_POINTER
+ SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
+ lw $a2, 64($sp) # pass referrer's Method*
+ move $a3, rSELF # pass Thread::Current
+ jal artGetCharInstanceFromCode # (field_idx, Object*, referrer, Thread*, $sp)
+ sw $sp, 16($sp) # pass $sp
+ RETURN_IF_NO_EXCEPTION
+END art_quick_get_char_instance
+ /*
+ * Called by managed code to resolve an instance field and load a short primitive value.
+ */
+ .extern artGetShortInstanceFromCode
+ENTRY art_quick_get_short_instance
+ GENERATE_GLOBAL_POINTER
+ SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
+ lw $a2, 64($sp) # pass referrer's Method*
+ move $a3, rSELF # pass Thread::Current
+ jal artGetShortInstanceFromCode # (field_idx, Object*, referrer, Thread*, $sp)
+ sw $sp, 16($sp) # pass $sp
+ RETURN_IF_NO_EXCEPTION
+END art_quick_get_short_instance
+
+ /*
* Called by managed code to resolve an instance field and load a 32-bit primitive value.
*/
.extern artGet32InstanceFromCode
@@ -825,6 +932,34 @@ ENTRY art_quick_get_obj_instance
END art_quick_get_obj_instance
/*
+ * Called by managed code to resolve a static field and store a 8-bit primitive value.
+ */
+ .extern artSet8StaticFromCode
+ENTRY art_quick_set8_static
+ GENERATE_GLOBAL_POINTER
+ SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
+ lw $a2, 64($sp) # pass referrer's Method*
+ move $a3, rSELF # pass Thread::Current
+ jal artSet8StaticFromCode # (field_idx, new_val, referrer, Thread*, $sp)
+ sw $sp, 16($sp) # pass $sp
+ RETURN_IF_ZERO
+END art_quick_set8_static
+
+ /*
+ * Called by managed code to resolve a static field and store a 16-bit primitive value.
+ */
+ .extern artSet16StaticFromCode
+ENTRY art_quick_set16_static
+ GENERATE_GLOBAL_POINTER
+ SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
+ lw $a2, 64($sp) # pass referrer's Method*
+ move $a3, rSELF # pass Thread::Current
+ jal artSet16StaticFromCode # (field_idx, new_val, referrer, Thread*, $sp)
+ sw $sp, 16($sp) # pass $sp
+ RETURN_IF_ZERO
+END art_quick_set16_static
+
+ /*
* Called by managed code to resolve a static field and store a 32-bit primitive value.
*/
.extern artSet32StaticFromCode
@@ -841,7 +976,7 @@ END art_quick_set32_static
/*
* Called by managed code to resolve a static field and store a 64-bit primitive value.
*/
- .extern artSet32StaticFromCode
+ .extern artSet64StaticFromCode
ENTRY art_quick_set64_static
GENERATE_GLOBAL_POINTER
SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
@@ -867,6 +1002,34 @@ ENTRY art_quick_set_obj_static
END art_quick_set_obj_static
/*
+ * Called by managed code to resolve an instance field and store a 8-bit primitive value.
+ */
+ .extern artSet8InstanceFromCode
+ENTRY art_quick_set8_instance
+ GENERATE_GLOBAL_POINTER
+ SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
+ lw $a3, 64($sp) # pass referrer's Method*
+ sw rSELF, 16($sp) # pass Thread::Current
+ jal artSet8InstanceFromCode # (field_idx, Object*, new_val, referrer, Thread*, $sp)
+ sw $sp, 20($sp) # pass $sp
+ RETURN_IF_ZERO
+END art_quick_set8_instance
+
+ /*
+ * Called by managed code to resolve an instance field and store a 16-bit primitive value.
+ */
+ .extern artSet16InstanceFromCode
+ENTRY art_quick_set16_instance
+ GENERATE_GLOBAL_POINTER
+ SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
+ lw $a3, 64($sp) # pass referrer's Method*
+ sw rSELF, 16($sp) # pass Thread::Current
+ jal artSet16InstanceFromCode # (field_idx, Object*, new_val, referrer, Thread*, $sp)
+ sw $sp, 20($sp) # pass $sp
+ RETURN_IF_ZERO
+END art_quick_set16_instance
+
+ /*
* Called by managed code to resolve an instance field and store a 32-bit primitive value.
*/
.extern artSet32InstanceFromCode
@@ -883,7 +1046,7 @@ END art_quick_set32_instance
/*
* Called by managed code to resolve an instance field and store a 64-bit primitive value.
*/
- .extern artSet32InstanceFromCode
+ .extern artSet64InstanceFromCode
ENTRY art_quick_set64_instance
GENERATE_GLOBAL_POINTER
SETUP_REF_ONLY_CALLEE_SAVE_FRAME # save callee saves in case of GC
diff --git a/runtime/arch/stub_test.cc b/runtime/arch/stub_test.cc
index 864e3f7ad0..1215d8b322 100644
--- a/runtime/arch/stub_test.cc
+++ b/runtime/arch/stub_test.cc
@@ -1306,6 +1306,288 @@ TEST_F(StubTest, StringCompareTo) {
}
+#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__))
+extern "C" void art_quick_set8_static(void);
+extern "C" void art_quick_get_byte_static(void);
+extern "C" void art_quick_get_boolean_static(void);
+#endif
+
+static void GetSetBooleanStatic(Handle<mirror::Object>* obj, Handle<mirror::ArtField>* f, Thread* self,
+ mirror::ArtMethod* referrer, StubTest* test)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__))
+ constexpr size_t num_values = 5;
+ uint8_t values[num_values] = { 0, 1, 2, 128, 0xFF };
+
+ for (size_t i = 0; i < num_values; ++i) {
+ test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ static_cast<size_t>(values[i]),
+ 0U,
+ StubTest::GetEntrypoint(self, kQuickSet8Static),
+ self,
+ referrer);
+
+ size_t res = test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ 0U, 0U,
+ StubTest::GetEntrypoint(self, kQuickGetBooleanStatic),
+ self,
+ referrer);
+ // Boolean currently stores bools as uint8_t, be more zealous about asserting correct writes/gets.
+ EXPECT_EQ(values[i], static_cast<uint8_t>(res)) << "Iteration " << i;
+ }
+#else
+ LOG(INFO) << "Skipping set_boolean_static as I don't know how to do that on " << kRuntimeISA;
+ // Force-print to std::cout so it's also outside the logcat.
+ std::cout << "Skipping set_boolean_static as I don't know how to do that on " << kRuntimeISA << std::endl;
+#endif
+}
+static void GetSetByteStatic(Handle<mirror::Object>* obj, Handle<mirror::ArtField>* f, Thread* self,
+ mirror::ArtMethod* referrer, StubTest* test)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__))
+ constexpr size_t num_values = 5;
+ int8_t values[num_values] = { -128, -64, 0, 64, 127 };
+
+ for (size_t i = 0; i < num_values; ++i) {
+ test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ static_cast<size_t>(values[i]),
+ 0U,
+ StubTest::GetEntrypoint(self, kQuickSet8Static),
+ self,
+ referrer);
+
+ size_t res = test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ 0U, 0U,
+ StubTest::GetEntrypoint(self, kQuickGetByteStatic),
+ self,
+ referrer);
+ EXPECT_EQ(values[i], static_cast<int8_t>(res)) << "Iteration " << i;
+ }
+#else
+ LOG(INFO) << "Skipping set_byte_static as I don't know how to do that on " << kRuntimeISA;
+ // Force-print to std::cout so it's also outside the logcat.
+ std::cout << "Skipping set_byte_static as I don't know how to do that on " << kRuntimeISA << std::endl;
+#endif
+}
+
+
+#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__))
+extern "C" void art_quick_set8_instance(void);
+extern "C" void art_quick_get_byte_instance(void);
+extern "C" void art_quick_get_boolean_instance(void);
+#endif
+
+static void GetSetBooleanInstance(Handle<mirror::Object>* obj, Handle<mirror::ArtField>* f,
+ Thread* self, mirror::ArtMethod* referrer, StubTest* test)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__))
+ constexpr size_t num_values = 5;
+ uint8_t values[num_values] = { 0, true, 2, 128, 0xFF };
+
+ for (size_t i = 0; i < num_values; ++i) {
+ test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ reinterpret_cast<size_t>(obj->Get()),
+ static_cast<size_t>(values[i]),
+ StubTest::GetEntrypoint(self, kQuickSet8Instance),
+ self,
+ referrer);
+
+ uint8_t res = f->Get()->GetBoolean(obj->Get());
+ EXPECT_EQ(values[i], res) << "Iteration " << i;
+
+ f->Get()->SetBoolean<false>(obj->Get(), res);
+
+ size_t res2 = test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ reinterpret_cast<size_t>(obj->Get()),
+ 0U,
+ StubTest::GetEntrypoint(self, kQuickGetBooleanInstance),
+ self,
+ referrer);
+ EXPECT_EQ(res, static_cast<uint8_t>(res2));
+ }
+#else
+ LOG(INFO) << "Skipping set_boolean_instance as I don't know how to do that on " << kRuntimeISA;
+ // Force-print to std::cout so it's also outside the logcat.
+ std::cout << "Skipping set_boolean_instance as I don't know how to do that on " << kRuntimeISA << std::endl;
+#endif
+}
+static void GetSetByteInstance(Handle<mirror::Object>* obj, Handle<mirror::ArtField>* f,
+ Thread* self, mirror::ArtMethod* referrer, StubTest* test)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__))
+ constexpr size_t num_values = 5;
+ int8_t values[num_values] = { -128, -64, 0, 64, 127 };
+
+ for (size_t i = 0; i < num_values; ++i) {
+ test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ reinterpret_cast<size_t>(obj->Get()),
+ static_cast<size_t>(values[i]),
+ StubTest::GetEntrypoint(self, kQuickSet8Instance),
+ self,
+ referrer);
+
+ int8_t res = f->Get()->GetByte(obj->Get());
+ EXPECT_EQ(res, values[i]) << "Iteration " << i;
+ f->Get()->SetByte<false>(obj->Get(), ++res);
+
+ size_t res2 = test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ reinterpret_cast<size_t>(obj->Get()),
+ 0U,
+ StubTest::GetEntrypoint(self, kQuickGetByteInstance),
+ self,
+ referrer);
+ EXPECT_EQ(res, static_cast<int8_t>(res2));
+ }
+#else
+ LOG(INFO) << "Skipping set_byte_instance as I don't know how to do that on " << kRuntimeISA;
+ // Force-print to std::cout so it's also outside the logcat.
+ std::cout << "Skipping set_byte_instance as I don't know how to do that on " << kRuntimeISA << std::endl;
+#endif
+}
+
+#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__))
+extern "C" void art_quick_set16_static(void);
+extern "C" void art_quick_get_short_static(void);
+extern "C" void art_quick_get_char_static(void);
+#endif
+
+static void GetSetCharStatic(Handle<mirror::Object>* obj, Handle<mirror::ArtField>* f, Thread* self,
+ mirror::ArtMethod* referrer, StubTest* test)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__))
+ constexpr size_t num_values = 6;
+ uint16_t values[num_values] = { 0, 1, 2, 255, 32768, 0xFFFF };
+
+ for (size_t i = 0; i < num_values; ++i) {
+ test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ static_cast<size_t>(values[i]),
+ 0U,
+ StubTest::GetEntrypoint(self, kQuickSet16Static),
+ self,
+ referrer);
+
+ size_t res = test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ 0U, 0U,
+ StubTest::GetEntrypoint(self, kQuickGetCharStatic),
+ self,
+ referrer);
+
+ EXPECT_EQ(values[i], static_cast<uint16_t>(res)) << "Iteration " << i;
+ }
+#else
+ LOG(INFO) << "Skipping set_char_static as I don't know how to do that on " << kRuntimeISA;
+ // Force-print to std::cout so it's also outside the logcat.
+ std::cout << "Skipping set_char_static as I don't know how to do that on " << kRuntimeISA << std::endl;
+#endif
+}
+static void GetSetShortStatic(Handle<mirror::Object>* obj, Handle<mirror::ArtField>* f, Thread* self,
+ mirror::ArtMethod* referrer, StubTest* test)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__))
+ constexpr size_t num_values = 6;
+ int16_t values[num_values] = { -0x7FFF, -32768, 0, 255, 32767, 0x7FFE };
+
+ for (size_t i = 0; i < num_values; ++i) {
+ test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ static_cast<size_t>(values[i]),
+ 0U,
+ StubTest::GetEntrypoint(self, kQuickSet16Static),
+ self,
+ referrer);
+
+ size_t res = test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ 0U, 0U,
+ StubTest::GetEntrypoint(self, kQuickGetShortStatic),
+ self,
+ referrer);
+
+ EXPECT_EQ(static_cast<int16_t>(res), values[i]) << "Iteration " << i;
+ }
+#else
+ LOG(INFO) << "Skipping set_short_static as I don't know how to do that on " << kRuntimeISA;
+ // Force-print to std::cout so it's also outside the logcat.
+ std::cout << "Skipping set_short_static as I don't know how to do that on " << kRuntimeISA << std::endl;
+#endif
+}
+
+#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__))
+extern "C" void art_quick_set16_instance(void);
+extern "C" void art_quick_get_short_instance(void);
+extern "C" void art_quick_get_char_instance(void);
+#endif
+
+static void GetSetCharInstance(Handle<mirror::Object>* obj, Handle<mirror::ArtField>* f,
+ Thread* self, mirror::ArtMethod* referrer, StubTest* test)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__))
+ constexpr size_t num_values = 6;
+ uint16_t values[num_values] = { 0, 1, 2, 255, 32768, 0xFFFF };
+
+ for (size_t i = 0; i < num_values; ++i) {
+ test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ reinterpret_cast<size_t>(obj->Get()),
+ static_cast<size_t>(values[i]),
+ StubTest::GetEntrypoint(self, kQuickSet16Instance),
+ self,
+ referrer);
+
+ uint16_t res = f->Get()->GetChar(obj->Get());
+ EXPECT_EQ(res, values[i]) << "Iteration " << i;
+ f->Get()->SetChar<false>(obj->Get(), ++res);
+
+ size_t res2 = test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ reinterpret_cast<size_t>(obj->Get()),
+ 0U,
+ StubTest::GetEntrypoint(self, kQuickGetCharInstance),
+ self,
+ referrer);
+ EXPECT_EQ(res, static_cast<uint16_t>(res2));
+ }
+#else
+ LOG(INFO) << "Skipping set_char_instance as I don't know how to do that on " << kRuntimeISA;
+ // Force-print to std::cout so it's also outside the logcat.
+ std::cout << "Skipping set_char_instance as I don't know how to do that on " << kRuntimeISA << std::endl;
+#endif
+}
+static void GetSetShortInstance(Handle<mirror::Object>* obj, Handle<mirror::ArtField>* f,
+ Thread* self, mirror::ArtMethod* referrer, StubTest* test)
+ SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
+#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__))
+ constexpr size_t num_values = 6;
+ int16_t values[num_values] = { -0x7FFF, -32768, 0, 255, 32767, 0x7FFE };
+
+ for (size_t i = 0; i < num_values; ++i) {
+ test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ reinterpret_cast<size_t>(obj->Get()),
+ static_cast<size_t>(values[i]),
+ StubTest::GetEntrypoint(self, kQuickSet16Instance),
+ self,
+ referrer);
+
+ int16_t res = f->Get()->GetShort(obj->Get());
+ EXPECT_EQ(res, values[i]) << "Iteration " << i;
+ f->Get()->SetShort<false>(obj->Get(), ++res);
+
+ size_t res2 = test->Invoke3WithReferrer(static_cast<size_t>((*f)->GetDexFieldIndex()),
+ reinterpret_cast<size_t>(obj->Get()),
+ 0U,
+ StubTest::GetEntrypoint(self, kQuickGetShortInstance),
+ self,
+ referrer);
+ EXPECT_EQ(res, static_cast<int16_t>(res2));
+ }
+#else
+ LOG(INFO) << "Skipping set_short_instance as I don't know how to do that on " << kRuntimeISA;
+ // Force-print to std::cout so it's also outside the logcat.
+ std::cout << "Skipping set_short_instance as I don't know how to do that on " << kRuntimeISA << std::endl;
+#endif
+}
+
+#if defined(__i386__) || defined(__arm__) || defined(__aarch64__) || (defined(__x86_64__) && !defined(__APPLE__))
+extern "C" void art_quick_set32_static(void);
+extern "C" void art_quick_get32_static(void);
+#endif
+
static void GetSet32Static(Handle<mirror::Object>* obj, Handle<mirror::ArtField>* f, Thread* self,
mirror::ArtMethod* referrer, StubTest* test)
SHARED_LOCKS_REQUIRED(Locks::mutator_lock_) {
@@ -1555,6 +1837,26 @@ static void TestFields(Thread* self, StubTest* test, Primitive::Type test_type)
Primitive::Type type = f->GetTypeAsPrimitiveType();
switch (type) {
+ case Primitive::Type::kPrimBoolean:
+ if (test_type == type) {
+ GetSetBooleanStatic(&obj, &f, self, m.Get(), test);
+ }
+ break;
+ case Primitive::Type::kPrimByte:
+ if (test_type == type) {
+ GetSetByteStatic(&obj, &f, self, m.Get(), test);
+ }
+ break;
+ case Primitive::Type::kPrimChar:
+ if (test_type == type) {
+ GetSetCharStatic(&obj, &f, self, m.Get(), test);
+ }
+ break;
+ case Primitive::Type::kPrimShort:
+ if (test_type == type) {
+ GetSetShortStatic(&obj, &f, self, m.Get(), test);
+ }
+ break;
case Primitive::Type::kPrimInt:
if (test_type == type) {
GetSet32Static(&obj, &f, self, m.Get(), test);
@@ -1590,6 +1892,26 @@ static void TestFields(Thread* self, StubTest* test, Primitive::Type test_type)
Primitive::Type type = f->GetTypeAsPrimitiveType();
switch (type) {
+ case Primitive::Type::kPrimBoolean:
+ if (test_type == type) {
+ GetSetBooleanInstance(&obj, &f, self, m.Get(), test);
+ }
+ break;
+ case Primitive::Type::kPrimByte:
+ if (test_type == type) {
+ GetSetByteInstance(&obj, &f, self, m.Get(), test);
+ }
+ break;
+ case Primitive::Type::kPrimChar:
+ if (test_type == type) {
+ GetSetCharInstance(&obj, &f, self, m.Get(), test);
+ }
+ break;
+ case Primitive::Type::kPrimShort:
+ if (test_type == type) {
+ GetSetShortInstance(&obj, &f, self, m.Get(), test);
+ }
+ break;
case Primitive::Type::kPrimInt:
if (test_type == type) {
GetSet32Instance(&obj, &f, self, m.Get(), test);
@@ -1618,6 +1940,33 @@ static void TestFields(Thread* self, StubTest* test, Primitive::Type test_type)
// TODO: Deallocate things.
}
+TEST_F(StubTest, Fields8) {
+ TEST_DISABLED_FOR_HEAP_REFERENCE_POISONING();
+
+ Thread* self = Thread::Current();
+
+ self->TransitionFromSuspendedToRunnable();
+ LoadDex("AllFields");
+ bool started = runtime_->Start();
+ CHECK(started);
+
+ TestFields(self, this, Primitive::Type::kPrimBoolean);
+ TestFields(self, this, Primitive::Type::kPrimByte);
+}
+
+TEST_F(StubTest, Fields16) {
+ TEST_DISABLED_FOR_HEAP_REFERENCE_POISONING();
+
+ Thread* self = Thread::Current();
+
+ self->TransitionFromSuspendedToRunnable();
+ LoadDex("AllFields");
+ bool started = runtime_->Start();
+ CHECK(started);
+
+ TestFields(self, this, Primitive::Type::kPrimChar);
+ TestFields(self, this, Primitive::Type::kPrimShort);
+}
TEST_F(StubTest, Fields32) {
TEST_DISABLED_FOR_HEAP_REFERENCE_POISONING();
diff --git a/runtime/arch/x86/entrypoints_init_x86.cc b/runtime/arch/x86/entrypoints_init_x86.cc
index a072996504..682c5021ce 100644
--- a/runtime/arch/x86/entrypoints_init_x86.cc
+++ b/runtime/arch/x86/entrypoints_init_x86.cc
@@ -47,12 +47,24 @@ extern "C" void* art_quick_initialize_type_and_verify_access(uint32_t, void*);
extern "C" void* art_quick_resolve_string(void*, uint32_t);
// Field entrypoints.
+extern "C" int art_quick_set8_instance(uint32_t, void*, int8_t);
+extern "C" int art_quick_set8_static(uint32_t, int8_t);
+extern "C" int art_quick_set16_instance(uint32_t, void*, int16_t);
+extern "C" int art_quick_set16_static(uint32_t, int16_t);
extern "C" int art_quick_set32_instance(uint32_t, void*, int32_t);
extern "C" int art_quick_set32_static(uint32_t, int32_t);
extern "C" int art_quick_set64_instance(uint32_t, void*, int64_t);
extern "C" int art_quick_set64_static(uint32_t, int64_t);
extern "C" int art_quick_set_obj_instance(uint32_t, void*, void*);
extern "C" int art_quick_set_obj_static(uint32_t, void*);
+extern "C" int8_t art_quick_get_byte_instance(uint32_t, void*);
+extern "C" uint8_t art_quick_get_boolean_instance(uint32_t, void*);
+extern "C" int8_t art_quick_get_byte_static(uint32_t);
+extern "C" uint8_t art_quick_get_boolean_static(uint32_t);
+extern "C" int16_t art_quick_get_short_instance(uint32_t, void*);
+extern "C" uint16_t art_quick_get_char_instance(uint32_t, void*);
+extern "C" int16_t art_quick_get_short_static(uint32_t);
+extern "C" uint16_t art_quick_get_char_static(uint32_t);
extern "C" int32_t art_quick_get32_instance(uint32_t, void*);
extern "C" int32_t art_quick_get32_static(uint32_t);
extern "C" int64_t art_quick_get64_instance(uint32_t, void*);
@@ -137,15 +149,27 @@ void InitEntryPoints(InterpreterEntryPoints* ipoints, JniEntryPoints* jpoints,
qpoints->pResolveString = art_quick_resolve_string;
// Field
+ qpoints->pSet8Instance = art_quick_set8_instance;
+ qpoints->pSet8Static = art_quick_set8_static;
+ qpoints->pSet16Instance = art_quick_set16_instance;
+ qpoints->pSet16Static = art_quick_set16_static;
qpoints->pSet32Instance = art_quick_set32_instance;
qpoints->pSet32Static = art_quick_set32_static;
qpoints->pSet64Instance = art_quick_set64_instance;
qpoints->pSet64Static = art_quick_set64_static;
qpoints->pSetObjInstance = art_quick_set_obj_instance;
qpoints->pSetObjStatic = art_quick_set_obj_static;
+ qpoints->pGetByteInstance = art_quick_get_byte_instance;
+ qpoints->pGetBooleanInstance = art_quick_get_boolean_instance;
+ qpoints->pGetShortInstance = art_quick_get_short_instance;
+ qpoints->pGetCharInstance = art_quick_get_char_instance;
qpoints->pGet32Instance = art_quick_get32_instance;
qpoints->pGet64Instance = art_quick_get64_instance;
qpoints->pGetObjInstance = art_quick_get_obj_instance;
+ qpoints->pGetByteStatic = art_quick_get_byte_static;
+ qpoints->pGetBooleanStatic = art_quick_get_boolean_static;
+ qpoints->pGetShortStatic = art_quick_get_short_static;
+ qpoints->pGetCharStatic = art_quick_get_char_static;
qpoints->pGet32Static = art_quick_get32_static;
qpoints->pGet64Static = art_quick_get64_static;
qpoints->pGetObjStatic = art_quick_get_obj_static;
diff --git a/runtime/arch/x86/quick_entrypoints_x86.S b/runtime/arch/x86/quick_entrypoints_x86.S
index c6e704a9cd..6166cb5cd5 100644
--- a/runtime/arch/x86/quick_entrypoints_x86.S
+++ b/runtime/arch/x86/quick_entrypoints_x86.S
@@ -384,6 +384,48 @@ MACRO3(THREE_ARG_DOWNCALL, c_name, cxx_name, return_macro)
END_FUNCTION RAW_VAR(c_name, 0)
END_MACRO
+MACRO3(ONE_ARG_REF_DOWNCALL, c_name, cxx_name, return_macro)
+ DEFINE_FUNCTION RAW_VAR(c_name, 0)
+ SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
+ mov %esp, %edx // remember SP
+ mov 32(%esp), %ecx // get referrer
+ // Outgoing argument set up
+ PUSH edx // pass SP
+ pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
+ CFI_ADJUST_CFA_OFFSET(4)
+ PUSH ecx // pass referrer
+ PUSH eax // pass arg1
+ call VAR(cxx_name, 1) // cxx_name(arg1, referrer, Thread*, SP)
+ addl MACRO_LITERAL(16), %esp // pop arguments
+ CFI_ADJUST_CFA_OFFSET(-16)
+ RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
+ CALL_MACRO(return_macro, 2) // return or deliver exception
+ END_FUNCTION RAW_VAR(c_name, 0)
+END_MACRO
+
+MACRO3(TWO_ARG_REF_DOWNCALL, c_name, cxx_name, return_macro)
+ DEFINE_FUNCTION RAW_VAR(c_name, 0)
+ SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
+ mov %esp, %ebx // remember SP
+ mov 32(%esp), %edx // get referrer
+ subl LITERAL(12), %esp // alignment padding
+ CFI_ADJUST_CFA_OFFSET(12)
+ PUSH ebx // pass SP
+ pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
+ CFI_ADJUST_CFA_OFFSET(4)
+ // Outgoing argument set up
+ PUSH edx // pass referrer
+ PUSH ecx // pass arg2
+ PUSH eax // pass arg1
+ call VAR(cxx_name, 1) // cxx_name(arg1, arg2, referrer, Thread*, SP)
+ addl LITERAL(32), %esp // pop arguments
+ CFI_ADJUST_CFA_OFFSET(-32)
+ RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
+ CALL_MACRO(return_macro, 2) // return or deliver exception
+ END_FUNCTION RAW_VAR(c_name, 0)
+END_MACRO
+
+
MACRO0(RETURN_IF_RESULT_IS_NON_ZERO)
testl %eax, %eax // eax == 0 ?
jz 1f // if eax == 0 goto 1
@@ -814,6 +856,46 @@ DEFINE_FUNCTION art_quick_lushr
ret
END_FUNCTION art_quick_lushr
+DEFINE_FUNCTION art_quick_set8_instance
+ SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
+ mov %esp, %ebx // remember SP
+ subl LITERAL(8), %esp // alignment padding
+ CFI_ADJUST_CFA_OFFSET(8)
+ PUSH ebx // pass SP
+ pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
+ CFI_ADJUST_CFA_OFFSET(4)
+ mov 32(%ebx), %ebx // get referrer
+ PUSH ebx // pass referrer
+ PUSH edx // pass new_val
+ PUSH ecx // pass object
+ PUSH eax // pass field_idx
+ call PLT_SYMBOL(artSet8InstanceFromCode) // (field_idx, Object*, new_val, referrer, Thread*, SP)
+ addl LITERAL(32), %esp // pop arguments
+ CFI_ADJUST_CFA_OFFSET(-32)
+ RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
+ RETURN_IF_EAX_ZERO // return or deliver exception
+END_FUNCTION art_quick_set8_instance
+
+DEFINE_FUNCTION art_quick_set16_instance
+ SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
+ mov %esp, %ebx // remember SP
+ subl LITERAL(8), %esp // alignment padding
+ CFI_ADJUST_CFA_OFFSET(8)
+ PUSH ebx // pass SP
+ pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
+ CFI_ADJUST_CFA_OFFSET(4)
+ mov 32(%ebx), %ebx // get referrer
+ PUSH ebx // pass referrer
+ PUSH edx // pass new_val
+ PUSH ecx // pass object
+ PUSH eax // pass field_idx
+ call PLT_SYMBOL(artSet16InstanceFromCode) // (field_idx, Object*, new_val, referrer, Thread*, SP)
+ addl LITERAL(32), %esp // pop arguments
+ CFI_ADJUST_CFA_OFFSET(-32)
+ RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
+ RETURN_IF_EAX_ZERO // return or deliver exception
+END_FUNCTION art_quick_set16_instance
+
DEFINE_FUNCTION art_quick_set32_instance
SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
mov %esp, %ebx // remember SP
@@ -873,8 +955,15 @@ DEFINE_FUNCTION art_quick_set_obj_instance
RETURN_IF_EAX_ZERO // return or deliver exception
END_FUNCTION art_quick_set_obj_instance
-DEFINE_FUNCTION art_quick_get32_instance
- SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
+TWO_ARG_REF_DOWNCALL art_quick_get_byte_instance, artGetByteInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION
+TWO_ARG_REF_DOWNCALL art_quick_get_boolean_instance, artGetBooleanInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION
+TWO_ARG_REF_DOWNCALL art_quick_get_short_instance, artGetShortInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION
+TWO_ARG_REF_DOWNCALL art_quick_get_char_instance, artGetCharInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION
+TWO_ARG_REF_DOWNCALL art_quick_get32_instance, artGet32InstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION
+TWO_ARG_REF_DOWNCALL art_quick_get_obj_instance, artGetObjInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION
+
+DEFINE_FUNCTION art_quick_get64_instance
+ SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
mov %esp, %ebx // remember SP
mov 32(%esp), %edx // get referrer
subl LITERAL(12), %esp // alignment padding
@@ -885,14 +974,14 @@ DEFINE_FUNCTION art_quick_get32_instance
PUSH edx // pass referrer
PUSH ecx // pass object
PUSH eax // pass field_idx
- call SYMBOL(artGet32InstanceFromCode) // (field_idx, Object*, referrer, Thread*, SP)
+ call SYMBOL(artGet64InstanceFromCode) // (field_idx, Object*, referrer, Thread*, SP)
addl LITERAL(32), %esp // pop arguments
CFI_ADJUST_CFA_OFFSET(-32)
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
-END_FUNCTION art_quick_get32_instance
+END_FUNCTION art_quick_get64_instance
-DEFINE_FUNCTION art_quick_get64_instance
+DEFINE_FUNCTION art_quick_set8_static
SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
mov %esp, %ebx // remember SP
mov 32(%esp), %edx // get referrer
@@ -902,16 +991,16 @@ DEFINE_FUNCTION art_quick_get64_instance
pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
CFI_ADJUST_CFA_OFFSET(4)
PUSH edx // pass referrer
- PUSH ecx // pass object
+ PUSH ecx // pass new_val
PUSH eax // pass field_idx
- call SYMBOL(artGet64InstanceFromCode) // (field_idx, Object*, referrer, Thread*, SP)
+ call SYMBOL(artSet8StaticFromCode) // (field_idx, new_val, referrer, Thread*, SP)
addl LITERAL(32), %esp // pop arguments
CFI_ADJUST_CFA_OFFSET(-32)
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
- RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
-END_FUNCTION art_quick_get64_instance
+ RETURN_IF_EAX_ZERO // return or deliver exception
+END_FUNCTION art_quick_set8_static
-DEFINE_FUNCTION art_quick_get_obj_instance
+DEFINE_FUNCTION art_quick_set16_static
SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
mov %esp, %ebx // remember SP
mov 32(%esp), %edx // get referrer
@@ -921,14 +1010,14 @@ DEFINE_FUNCTION art_quick_get_obj_instance
pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
CFI_ADJUST_CFA_OFFSET(4)
PUSH edx // pass referrer
- PUSH ecx // pass object
+ PUSH ecx // pass new_val
PUSH eax // pass field_idx
- call SYMBOL(artGetObjInstanceFromCode) // (field_idx, Object*, referrer, Thread*, SP)
+ call SYMBOL(artSet16StaticFromCode) // (field_idx, new_val, referrer, Thread*, SP)
addl LITERAL(32), %esp // pop arguments
CFI_ADJUST_CFA_OFFSET(-32)
RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
- RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
-END_FUNCTION art_quick_get_obj_instance
+ RETURN_IF_EAX_ZERO // return or deliver exception
+END_FUNCTION art_quick_set16_static
DEFINE_FUNCTION art_quick_set32_static
SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
@@ -987,53 +1076,13 @@ DEFINE_FUNCTION art_quick_set_obj_static
RETURN_IF_EAX_ZERO // return or deliver exception
END_FUNCTION art_quick_set_obj_static
-DEFINE_FUNCTION art_quick_get32_static
- SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
- mov %esp, %edx // remember SP
- mov 32(%esp), %ecx // get referrer
- PUSH edx // pass SP
- pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
- CFI_ADJUST_CFA_OFFSET(4)
- PUSH ecx // pass referrer
- PUSH eax // pass field_idx
- call SYMBOL(artGet32StaticFromCode) // (field_idx, referrer, Thread*, SP)
- addl LITERAL(16), %esp // pop arguments
- CFI_ADJUST_CFA_OFFSET(-16)
- RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
- RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
-END_FUNCTION art_quick_get32_static
-
-DEFINE_FUNCTION art_quick_get64_static
- SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
- mov %esp, %edx // remember SP
- mov 32(%esp), %ecx // get referrer
- PUSH edx // pass SP
- pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
- CFI_ADJUST_CFA_OFFSET(4)
- PUSH ecx // pass referrer
- PUSH eax // pass field_idx
- call SYMBOL(artGet64StaticFromCode) // (field_idx, referrer, Thread*, SP)
- addl LITERAL(16), %esp // pop arguments
- CFI_ADJUST_CFA_OFFSET(-16)
- RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
- RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
-END_FUNCTION art_quick_get64_static
-
-DEFINE_FUNCTION art_quick_get_obj_static
- SETUP_REF_ONLY_CALLEE_SAVE_FRAME // save ref containing registers for GC
- mov %esp, %edx // remember SP
- mov 32(%esp), %ecx // get referrer
- PUSH edx // pass SP
- pushl %fs:THREAD_SELF_OFFSET // pass Thread::Current()
- CFI_ADJUST_CFA_OFFSET(4)
- PUSH ecx // pass referrer
- PUSH eax // pass field_idx
- call SYMBOL(artGetObjStaticFromCode) // (field_idx, referrer, Thread*, SP)
- addl LITERAL(16), %esp // pop arguments
- CFI_ADJUST_CFA_OFFSET(-16)
- RESTORE_REF_ONLY_CALLEE_SAVE_FRAME // restore frame up to return address
- RETURN_OR_DELIVER_PENDING_EXCEPTION // return or deliver exception
-END_FUNCTION art_quick_get_obj_static
+ONE_ARG_REF_DOWNCALL art_quick_get_byte_static, artGetByteStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION
+ONE_ARG_REF_DOWNCALL art_quick_get_boolean_static, artGetBooleanStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION
+ONE_ARG_REF_DOWNCALL art_quick_get_short_static, artGetShortStaticFromCode RETURN_OR_DELIVER_PENDING_EXCEPTION
+ONE_ARG_REF_DOWNCALL art_quick_get_char_static, artGetCharStaticFromCode RETURN_OR_DELIVER_PENDING_EXCEPTION
+ONE_ARG_REF_DOWNCALL art_quick_get32_static, artGet32StaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION
+ONE_ARG_REF_DOWNCALL art_quick_get64_static, artGet64StaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION
+ONE_ARG_REF_DOWNCALL art_quick_get_obj_static, artGetObjStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION
DEFINE_FUNCTION art_quick_proxy_invoke_handler
SETUP_REF_AND_ARGS_CALLEE_SAVE_FRAME // save frame and Method*
diff --git a/runtime/arch/x86_64/entrypoints_init_x86_64.cc b/runtime/arch/x86_64/entrypoints_init_x86_64.cc
index 35a0cf4f2c..c9028e1355 100644
--- a/runtime/arch/x86_64/entrypoints_init_x86_64.cc
+++ b/runtime/arch/x86_64/entrypoints_init_x86_64.cc
@@ -48,12 +48,24 @@ extern "C" void* art_quick_initialize_type_and_verify_access(uint32_t, void*);
extern "C" void* art_quick_resolve_string(void*, uint32_t);
// Field entrypoints.
+extern "C" int art_quick_set8_instance(uint32_t, void*, int8_t);
+extern "C" int art_quick_set8_static(uint32_t, int8_t);
+extern "C" int art_quick_set16_instance(uint32_t, void*, int16_t);
+extern "C" int art_quick_set16_static(uint32_t, int16_t);
extern "C" int art_quick_set32_instance(uint32_t, void*, int32_t);
extern "C" int art_quick_set32_static(uint32_t, int32_t);
extern "C" int art_quick_set64_instance(uint32_t, void*, int64_t);
extern "C" int art_quick_set64_static(uint32_t, int64_t);
extern "C" int art_quick_set_obj_instance(uint32_t, void*, void*);
extern "C" int art_quick_set_obj_static(uint32_t, void*);
+extern "C" int8_t art_quick_get_byte_instance(uint32_t, void*);
+extern "C" uint8_t art_quick_get_boolean_instance(uint32_t, void*);
+extern "C" int8_t art_quick_get_byte_static(uint32_t);
+extern "C" uint8_t art_quick_get_boolean_static(uint32_t);
+extern "C" int16_t art_quick_get_short_instance(uint32_t, void*);
+extern "C" uint16_t art_quick_get_char_instance(uint32_t, void*);
+extern "C" int16_t art_quick_get_short_static(uint32_t);
+extern "C" uint16_t art_quick_get_char_static(uint32_t);
extern "C" int32_t art_quick_get32_instance(uint32_t, void*);
extern "C" int32_t art_quick_get32_static(uint32_t);
extern "C" int64_t art_quick_get64_instance(uint32_t, void*);
@@ -141,15 +153,27 @@ void InitEntryPoints(InterpreterEntryPoints* ipoints, JniEntryPoints* jpoints,
qpoints->pResolveString = art_quick_resolve_string;
// Field
+ qpoints->pSet8Instance = art_quick_set8_instance;
+ qpoints->pSet8Static = art_quick_set8_static;
+ qpoints->pSet16Instance = art_quick_set16_instance;
+ qpoints->pSet16Static = art_quick_set16_static;
qpoints->pSet32Instance = art_quick_set32_instance;
qpoints->pSet32Static = art_quick_set32_static;
qpoints->pSet64Instance = art_quick_set64_instance;
qpoints->pSet64Static = art_quick_set64_static;
qpoints->pSetObjInstance = art_quick_set_obj_instance;
qpoints->pSetObjStatic = art_quick_set_obj_static;
+ qpoints->pGetByteInstance = art_quick_get_byte_instance;
+ qpoints->pGetBooleanInstance = art_quick_get_boolean_instance;
+ qpoints->pGetShortInstance = art_quick_get_short_instance;
+ qpoints->pGetCharInstance = art_quick_get_char_instance;
qpoints->pGet32Instance = art_quick_get32_instance;
qpoints->pGet64Instance = art_quick_get64_instance;
qpoints->pGetObjInstance = art_quick_get_obj_instance;
+ qpoints->pGetByteStatic = art_quick_get_byte_static;
+ qpoints->pGetBooleanStatic = art_quick_get_boolean_static;
+ qpoints->pGetShortStatic = art_quick_get_short_static;
+ qpoints->pGetCharStatic = art_quick_get_char_static;
qpoints->pGet32Static = art_quick_get32_static;
qpoints->pGet64Static = art_quick_get64_static;
qpoints->pGetObjStatic = art_quick_get_obj_static;
diff --git a/runtime/arch/x86_64/quick_entrypoints_x86_64.S b/runtime/arch/x86_64/quick_entrypoints_x86_64.S
index f95bd22e9f..e9b5a7274b 100644
--- a/runtime/arch/x86_64/quick_entrypoints_x86_64.S
+++ b/runtime/arch/x86_64/quick_entrypoints_x86_64.S
@@ -1076,17 +1076,29 @@ UNIMPLEMENTED art_quick_lshl
UNIMPLEMENTED art_quick_lshr
UNIMPLEMENTED art_quick_lushr
+THREE_ARG_REF_DOWNCALL art_quick_set8_instance, artSet8InstanceFromCode, RETURN_IF_EAX_ZERO
+THREE_ARG_REF_DOWNCALL art_quick_set16_instance, artSet16InstanceFromCode, RETURN_IF_EAX_ZERO
THREE_ARG_REF_DOWNCALL art_quick_set32_instance, artSet32InstanceFromCode, RETURN_IF_EAX_ZERO
THREE_ARG_DOWNCALL art_quick_set64_instance, artSet64InstanceFromCode, RETURN_IF_EAX_ZERO
THREE_ARG_REF_DOWNCALL art_quick_set_obj_instance, artSetObjInstanceFromCode, RETURN_IF_EAX_ZERO
+TWO_ARG_REF_DOWNCALL art_quick_get_byte_instance, artGetByteInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION
+TWO_ARG_REF_DOWNCALL art_quick_get_boolean_instance, artGetBooleanInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION
+TWO_ARG_REF_DOWNCALL art_quick_get_short_instance, artGetShortInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION
+TWO_ARG_REF_DOWNCALL art_quick_get_char_instance, artGetCharInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION
TWO_ARG_REF_DOWNCALL art_quick_get32_instance, artGet32InstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION
TWO_ARG_REF_DOWNCALL art_quick_get64_instance, artGet64InstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION
TWO_ARG_REF_DOWNCALL art_quick_get_obj_instance, artGetObjInstanceFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION
+TWO_ARG_REF_DOWNCALL art_quick_set8_static, artSet8StaticFromCode, RETURN_IF_EAX_ZERO
+TWO_ARG_REF_DOWNCALL art_quick_set16_static, artSet16StaticFromCode, RETURN_IF_EAX_ZERO
TWO_ARG_REF_DOWNCALL art_quick_set32_static, artSet32StaticFromCode, RETURN_IF_EAX_ZERO
TWO_ARG_REF_DOWNCALL art_quick_set_obj_static, artSetObjStaticFromCode, RETURN_IF_EAX_ZERO
+ONE_ARG_REF_DOWNCALL art_quick_get_byte_static, artGetByteStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION
+ONE_ARG_REF_DOWNCALL art_quick_get_boolean_static, artGetBooleanStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION
+ONE_ARG_REF_DOWNCALL art_quick_get_short_static, artGetShortStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION
+ONE_ARG_REF_DOWNCALL art_quick_get_char_static, artGetCharStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION
ONE_ARG_REF_DOWNCALL art_quick_get32_static, artGet32StaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION
ONE_ARG_REF_DOWNCALL art_quick_get64_static, artGet64StaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION
ONE_ARG_REF_DOWNCALL art_quick_get_obj_static, artGetObjStaticFromCode, RETURN_OR_DELIVER_PENDING_EXCEPTION