summaryrefslogtreecommitdiff
path: root/runtime/interpreter/interpreter_common.cc
diff options
context:
space:
mode:
Diffstat (limited to 'runtime/interpreter/interpreter_common.cc')
-rw-r--r--runtime/interpreter/interpreter_common.cc29
1 files changed, 24 insertions, 5 deletions
diff --git a/runtime/interpreter/interpreter_common.cc b/runtime/interpreter/interpreter_common.cc
index 136d0c6b64..f8cb243c01 100644
--- a/runtime/interpreter/interpreter_common.cc
+++ b/runtime/interpreter/interpreter_common.cc
@@ -33,6 +33,7 @@
#include "reflection.h"
#include "stack.h"
#include "thread-inl.h"
+#include "transaction.h"
#include "well_known_classes.h"
namespace art {
@@ -42,7 +43,8 @@ void ThrowNullPointerExceptionFromInterpreter() {
ThrowNullPointerExceptionFromDexPC();
}
-template<FindFieldType find_type, Primitive::Type field_type, bool do_access_check>
+template<FindFieldType find_type, Primitive::Type field_type, bool do_access_check,
+ bool transaction_active>
bool DoFieldGet(Thread* self, ShadowFrame& shadow_frame, const Instruction* inst,
uint16_t inst_data) {
const bool is_static = (find_type == StaticObjectRead) || (find_type == StaticPrimitiveRead);
@@ -57,6 +59,13 @@ bool DoFieldGet(Thread* self, ShadowFrame& shadow_frame, const Instruction* inst
ObjPtr<mirror::Object> obj;
if (is_static) {
obj = f->GetDeclaringClass();
+ if (transaction_active) {
+ if (Runtime::Current()->GetTransaction()->ReadConstraint(obj.Ptr(), f)) {
+ Runtime::Current()->AbortTransactionAndThrowAbortError(self, "Can't read static fields of "
+ + obj->PrettyTypeOf() + " since it does not belong to clinit's class.");
+ return false;
+ }
+ }
} else {
obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
if (UNLIKELY(obj == nullptr)) {
@@ -102,15 +111,17 @@ bool DoFieldGet(Thread* self, ShadowFrame& shadow_frame, const Instruction* inst
}
// Explicitly instantiate all DoFieldGet functions.
-#define EXPLICIT_DO_FIELD_GET_TEMPLATE_DECL(_find_type, _field_type, _do_check) \
- template bool DoFieldGet<_find_type, _field_type, _do_check>(Thread* self, \
+#define EXPLICIT_DO_FIELD_GET_TEMPLATE_DECL(_find_type, _field_type, _do_check, _transaction_active) \
+ template bool DoFieldGet<_find_type, _field_type, _do_check, _transaction_active>(Thread* self, \
ShadowFrame& shadow_frame, \
const Instruction* inst, \
uint16_t inst_data)
#define EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(_find_type, _field_type) \
- EXPLICIT_DO_FIELD_GET_TEMPLATE_DECL(_find_type, _field_type, false); \
- EXPLICIT_DO_FIELD_GET_TEMPLATE_DECL(_find_type, _field_type, true);
+ EXPLICIT_DO_FIELD_GET_TEMPLATE_DECL(_find_type, _field_type, false, true); \
+ EXPLICIT_DO_FIELD_GET_TEMPLATE_DECL(_find_type, _field_type, false, false); \
+ EXPLICIT_DO_FIELD_GET_TEMPLATE_DECL(_find_type, _field_type, true, true); \
+ EXPLICIT_DO_FIELD_GET_TEMPLATE_DECL(_find_type, _field_type, true, false);
// iget-XXX
EXPLICIT_DO_FIELD_GET_ALL_TEMPLATE_DECL(InstancePrimitiveRead, Primitive::kPrimBoolean)
@@ -261,6 +272,14 @@ bool DoFieldPut(Thread* self, const ShadowFrame& shadow_frame, const Instruction
ObjPtr<mirror::Object> obj;
if (is_static) {
obj = f->GetDeclaringClass();
+ if (transaction_active) {
+ if (Runtime::Current()->GetTransaction()->WriteConstraint(obj.Ptr(), f)) {
+ Runtime::Current()->AbortTransactionAndThrowAbortError(
+ self, "Can't set fields of " + obj->PrettyTypeOf());
+ return false;
+ }
+ }
+
} else {
obj = shadow_frame.GetVRegReference(inst->VRegB_22c(inst_data));
if (UNLIKELY(obj == nullptr)) {