diff src/share/vm/runtime/deoptimization.cpp @ 12617:bca33c3135de

PEA: support for unsafe stores of mismatching sizes, cleanup, documentation
author Lukas Stadler <lukas.stadler@jku.at>
date Mon, 28 Oct 2013 13:01:16 +0100
parents d1f8d0538b79
children 38b84d5a66fd
line wrap: on
line diff
--- a/src/share/vm/runtime/deoptimization.cpp	Mon Oct 28 13:10:10 2013 +0200
+++ b/src/share/vm/runtime/deoptimization.cpp	Mon Oct 28 13:01:16 2013 +0100
@@ -914,7 +914,8 @@
   fields->sort(compare);
   for (int i = 0; i < fields->length(); i++) {
     intptr_t val;
-    StackValue* value = StackValue::create_stack_value(fr, reg_map, sv->field_at(svIndex));
+    ScopeValue* scope_field = sv->field_at(svIndex);
+    StackValue* value = StackValue::create_stack_value(fr, reg_map, scope_field);
     int offset = fields->at(i)._offset;
     BasicType type = fields->at(i)._type;
     switch (type) {
@@ -923,6 +924,37 @@
         obj->obj_field_put(offset, value->get_obj()());
         break;
 
+      // Have to cast to INT (32 bits) pointer to avoid little/big-endian problem.
+      case T_INT: case T_FLOAT: { // 4 bytes.
+        assert(value->type() == T_INT, "Agreement.");
+        bool big_value = false;
+        if (i+1 < fields->length() && fields->at(i+1)._type == T_INT) {
+          if (scope_field->is_location()) {
+            Location::Type type = ((LocationValue*) scope_field)->location().type();
+            if (type == Location::dbl || type == Location::lng) {
+              big_value = true;
+            }
+          }
+          if (scope_field->is_constant_int()) {
+            ScopeValue* next_scope_field = sv->field_at(svIndex + 1);
+            if (next_scope_field->is_constant_long() || next_scope_field->is_constant_double()) {
+              big_value = true;
+            }
+          }
+        }
+
+        if (big_value) {
+          i++;
+          assert(i < fields->length(), "second T_INT field needed");
+          assert(fields->at(i)._type == T_INT, "T_INT field needed");
+        } else {
+          val = value->get_int();
+          obj->int_field_put(offset, (jint)*((jint*)&val));
+          break;
+        }
+      }
+        /* no break */
+
       case T_LONG: case T_DOUBLE: {
         assert(value->type() == T_INT, "Agreement.");
         StackValue* low = StackValue::create_stack_value(fr, reg_map, sv->field_at(++svIndex));
@@ -939,12 +971,6 @@
         obj->long_field_put(offset, res);
         break;
       }
-      // Have to cast to INT (32 bits) pointer to avoid little/big-endian problem.
-      case T_INT: case T_FLOAT: // 4 bytes.
-        assert(value->type() == T_INT, "Agreement.");
-        val = value->get_int();
-        obj->int_field_put(offset, (jint)*((jint*)&val));
-        break;
 
       case T_SHORT: case T_CHAR: // 2 bytes
         assert(value->type() == T_INT, "Agreement.");