src/cpu/sparc/vm/c1_FrameMap_sparc.cpp

Thu, 07 Apr 2011 09:53:20 -0700

author
johnc
date
Thu, 07 Apr 2011 09:53:20 -0700
changeset 2781
e1162778c1c8
parent 2314
f95d63e2154a
child 4051
8a02ca5e5576
permissions
-rw-r--r--

7009266: G1: assert(obj->is_oop_or_null(true )) failed: Error
Summary: A referent object that is only weakly reachable at the start of concurrent marking but is re-attached to the strongly reachable object graph during marking may not be marked as live. This can cause the reference object to be processed prematurely and leave dangling pointers to the referent object. Implement a read barrier for the java.lang.ref.Reference::referent field by intrinsifying the Reference.get() method, and intercepting accesses though JNI, reflection, and Unsafe, so that when a non-null referent object is read it is also logged in an SATB buffer.
Reviewed-by: kvn, iveresov, never, tonyp, dholmes

     1 /*
     2  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     4  *
     5  * This code is free software; you can redistribute it and/or modify it
     6  * under the terms of the GNU General Public License version 2 only, as
     7  * published by the Free Software Foundation.
     8  *
     9  * This code is distributed in the hope that it will be useful, but WITHOUT
    10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
    12  * version 2 for more details (a copy is included in the LICENSE file that
    13  * accompanied this code).
    14  *
    15  * You should have received a copy of the GNU General Public License version
    16  * 2 along with this work; if not, write to the Free Software Foundation,
    17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
    18  *
    19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
    20  * or visit www.oracle.com if you need additional information or have any
    21  * questions.
    22  *
    23  */
    25 #include "precompiled.hpp"
    26 #include "c1/c1_FrameMap.hpp"
    27 #include "c1/c1_LIR.hpp"
    28 #include "runtime/sharedRuntime.hpp"
    29 #include "vmreg_sparc.inline.hpp"
    32 const int FrameMap::pd_c_runtime_reserved_arg_size = 7;
    35 LIR_Opr FrameMap::map_to_opr(BasicType type, VMRegPair* reg, bool outgoing) {
    36   LIR_Opr opr = LIR_OprFact::illegalOpr;
    37   VMReg r_1 = reg->first();
    38   VMReg r_2 = reg->second();
    39   if (r_1->is_stack()) {
    40     // Convert stack slot to an SP offset
    41     // The calling convention does not count the SharedRuntime::out_preserve_stack_slots() value
    42     // so we must add it in here.
    43     int st_off = (r_1->reg2stack() + SharedRuntime::out_preserve_stack_slots()) * VMRegImpl::stack_slot_size;
    44     opr = LIR_OprFact::address(new LIR_Address(SP_opr, st_off + STACK_BIAS, type));
    45   } else if (r_1->is_Register()) {
    46     Register reg = r_1->as_Register();
    47     if (outgoing) {
    48       assert(!reg->is_in(), "should be using I regs");
    49     } else {
    50       assert(!reg->is_out(), "should be using O regs");
    51     }
    52     if (r_2->is_Register() && (type == T_LONG || type == T_DOUBLE)) {
    53       opr = as_long_opr(reg);
    54     } else if (type == T_OBJECT || type == T_ARRAY) {
    55       opr = as_oop_opr(reg);
    56     } else {
    57       opr = as_opr(reg);
    58     }
    59   } else if (r_1->is_FloatRegister()) {
    60     assert(type == T_DOUBLE || type == T_FLOAT, "wrong type");
    61     FloatRegister f = r_1->as_FloatRegister();
    62     if (type == T_DOUBLE) {
    63       opr = as_double_opr(f);
    64     } else {
    65       opr = as_float_opr(f);
    66     }
    67   }
    68   return opr;
    69 }
    71 //               FrameMap
    72 //--------------------------------------------------------
    74 FloatRegister FrameMap::_fpu_regs [FrameMap::nof_fpu_regs];
    76 // some useful constant RInfo's:
    77 LIR_Opr FrameMap::in_long_opr;
    78 LIR_Opr FrameMap::out_long_opr;
    79 LIR_Opr FrameMap::g1_long_single_opr;
    81 LIR_Opr FrameMap::F0_opr;
    82 LIR_Opr FrameMap::F0_double_opr;
    84 LIR_Opr FrameMap::G0_opr;
    85 LIR_Opr FrameMap::G1_opr;
    86 LIR_Opr FrameMap::G2_opr;
    87 LIR_Opr FrameMap::G3_opr;
    88 LIR_Opr FrameMap::G4_opr;
    89 LIR_Opr FrameMap::G5_opr;
    90 LIR_Opr FrameMap::G6_opr;
    91 LIR_Opr FrameMap::G7_opr;
    92 LIR_Opr FrameMap::O0_opr;
    93 LIR_Opr FrameMap::O1_opr;
    94 LIR_Opr FrameMap::O2_opr;
    95 LIR_Opr FrameMap::O3_opr;
    96 LIR_Opr FrameMap::O4_opr;
    97 LIR_Opr FrameMap::O5_opr;
    98 LIR_Opr FrameMap::O6_opr;
    99 LIR_Opr FrameMap::O7_opr;
   100 LIR_Opr FrameMap::L0_opr;
   101 LIR_Opr FrameMap::L1_opr;
   102 LIR_Opr FrameMap::L2_opr;
   103 LIR_Opr FrameMap::L3_opr;
   104 LIR_Opr FrameMap::L4_opr;
   105 LIR_Opr FrameMap::L5_opr;
   106 LIR_Opr FrameMap::L6_opr;
   107 LIR_Opr FrameMap::L7_opr;
   108 LIR_Opr FrameMap::I0_opr;
   109 LIR_Opr FrameMap::I1_opr;
   110 LIR_Opr FrameMap::I2_opr;
   111 LIR_Opr FrameMap::I3_opr;
   112 LIR_Opr FrameMap::I4_opr;
   113 LIR_Opr FrameMap::I5_opr;
   114 LIR_Opr FrameMap::I6_opr;
   115 LIR_Opr FrameMap::I7_opr;
   117 LIR_Opr FrameMap::G0_oop_opr;
   118 LIR_Opr FrameMap::G1_oop_opr;
   119 LIR_Opr FrameMap::G2_oop_opr;
   120 LIR_Opr FrameMap::G3_oop_opr;
   121 LIR_Opr FrameMap::G4_oop_opr;
   122 LIR_Opr FrameMap::G5_oop_opr;
   123 LIR_Opr FrameMap::G6_oop_opr;
   124 LIR_Opr FrameMap::G7_oop_opr;
   125 LIR_Opr FrameMap::O0_oop_opr;
   126 LIR_Opr FrameMap::O1_oop_opr;
   127 LIR_Opr FrameMap::O2_oop_opr;
   128 LIR_Opr FrameMap::O3_oop_opr;
   129 LIR_Opr FrameMap::O4_oop_opr;
   130 LIR_Opr FrameMap::O5_oop_opr;
   131 LIR_Opr FrameMap::O6_oop_opr;
   132 LIR_Opr FrameMap::O7_oop_opr;
   133 LIR_Opr FrameMap::L0_oop_opr;
   134 LIR_Opr FrameMap::L1_oop_opr;
   135 LIR_Opr FrameMap::L2_oop_opr;
   136 LIR_Opr FrameMap::L3_oop_opr;
   137 LIR_Opr FrameMap::L4_oop_opr;
   138 LIR_Opr FrameMap::L5_oop_opr;
   139 LIR_Opr FrameMap::L6_oop_opr;
   140 LIR_Opr FrameMap::L7_oop_opr;
   141 LIR_Opr FrameMap::I0_oop_opr;
   142 LIR_Opr FrameMap::I1_oop_opr;
   143 LIR_Opr FrameMap::I2_oop_opr;
   144 LIR_Opr FrameMap::I3_oop_opr;
   145 LIR_Opr FrameMap::I4_oop_opr;
   146 LIR_Opr FrameMap::I5_oop_opr;
   147 LIR_Opr FrameMap::I6_oop_opr;
   148 LIR_Opr FrameMap::I7_oop_opr;
   150 LIR_Opr FrameMap::SP_opr;
   151 LIR_Opr FrameMap::FP_opr;
   153 LIR_Opr FrameMap::Oexception_opr;
   154 LIR_Opr FrameMap::Oissuing_pc_opr;
   156 LIR_Opr FrameMap::_caller_save_cpu_regs[] = { 0, };
   157 LIR_Opr FrameMap::_caller_save_fpu_regs[] = { 0, };
   160 FloatRegister FrameMap::nr2floatreg (int rnr) {
   161   assert(_init_done, "tables not initialized");
   162   debug_only(fpu_range_check(rnr);)
   163   return _fpu_regs[rnr];
   164 }
   167 // returns true if reg could be smashed by a callee.
   168 bool FrameMap::is_caller_save_register (LIR_Opr reg) {
   169   if (reg->is_single_fpu() || reg->is_double_fpu()) { return true; }
   170   if (reg->is_double_cpu()) {
   171     return is_caller_save_register(reg->as_register_lo()) ||
   172            is_caller_save_register(reg->as_register_hi());
   173   }
   174   return is_caller_save_register(reg->as_register());
   175 }
   178 NEEDS_CLEANUP   // once the new calling convention is enabled, we no
   179                 // longer need to treat I5, I4 and L0 specially
   180 // Because the interpreter destroys caller's I5, I4 and L0,
   181 // we must spill them before doing a Java call as we may land in
   182 // interpreter.
   183 bool FrameMap::is_caller_save_register (Register r) {
   184   return (r->is_global() && (r != G0)) || r->is_out();
   185 }
   188 void FrameMap::initialize() {
   189   assert(!_init_done, "once");
   191   int i=0;
   192   // Register usage:
   193   //  O6: sp
   194   //  I6: fp
   195   //  I7: return address
   196   //  G0: zero
   197   //  G2: thread
   198   //  G7: not available
   199   //  G6: not available
   200   /*  0 */ map_register(i++, L0);
   201   /*  1 */ map_register(i++, L1);
   202   /*  2 */ map_register(i++, L2);
   203   /*  3 */ map_register(i++, L3);
   204   /*  4 */ map_register(i++, L4);
   205   /*  5 */ map_register(i++, L5);
   206   /*  6 */ map_register(i++, L6);
   207   /*  7 */ map_register(i++, L7);
   209   /*  8 */ map_register(i++, I0);
   210   /*  9 */ map_register(i++, I1);
   211   /* 10 */ map_register(i++, I2);
   212   /* 11 */ map_register(i++, I3);
   213   /* 12 */ map_register(i++, I4);
   214   /* 13 */ map_register(i++, I5);
   215   /* 14 */ map_register(i++, O0);
   216   /* 15 */ map_register(i++, O1);
   217   /* 16 */ map_register(i++, O2);
   218   /* 17 */ map_register(i++, O3);
   219   /* 18 */ map_register(i++, O4);
   220   /* 19 */ map_register(i++, O5); // <- last register visible in RegAlloc (RegAlloc::nof+cpu_regs)
   221   /* 20 */ map_register(i++, G1);
   222   /* 21 */ map_register(i++, G3);
   223   /* 22 */ map_register(i++, G4);
   224   /* 23 */ map_register(i++, G5);
   225   /* 24 */ map_register(i++, G0);
   227   // the following registers are not normally available
   228   /* 25 */ map_register(i++, O7);
   229   /* 26 */ map_register(i++, G2);
   230   /* 27 */ map_register(i++, O6);
   231   /* 28 */ map_register(i++, I6);
   232   /* 29 */ map_register(i++, I7);
   233   /* 30 */ map_register(i++, G6);
   234   /* 31 */ map_register(i++, G7);
   235   assert(i == nof_cpu_regs, "number of CPU registers");
   237   for (i = 0; i < nof_fpu_regs; i++) {
   238     _fpu_regs[i] = as_FloatRegister(i);
   239   }
   241   _init_done = true;
   243   in_long_opr    = as_long_opr(I0);
   244   out_long_opr   = as_long_opr(O0);
   245   g1_long_single_opr    = as_long_single_opr(G1);
   247   G0_opr = as_opr(G0);
   248   G1_opr = as_opr(G1);
   249   G2_opr = as_opr(G2);
   250   G3_opr = as_opr(G3);
   251   G4_opr = as_opr(G4);
   252   G5_opr = as_opr(G5);
   253   G6_opr = as_opr(G6);
   254   G7_opr = as_opr(G7);
   255   O0_opr = as_opr(O0);
   256   O1_opr = as_opr(O1);
   257   O2_opr = as_opr(O2);
   258   O3_opr = as_opr(O3);
   259   O4_opr = as_opr(O4);
   260   O5_opr = as_opr(O5);
   261   O6_opr = as_opr(O6);
   262   O7_opr = as_opr(O7);
   263   L0_opr = as_opr(L0);
   264   L1_opr = as_opr(L1);
   265   L2_opr = as_opr(L2);
   266   L3_opr = as_opr(L3);
   267   L4_opr = as_opr(L4);
   268   L5_opr = as_opr(L5);
   269   L6_opr = as_opr(L6);
   270   L7_opr = as_opr(L7);
   271   I0_opr = as_opr(I0);
   272   I1_opr = as_opr(I1);
   273   I2_opr = as_opr(I2);
   274   I3_opr = as_opr(I3);
   275   I4_opr = as_opr(I4);
   276   I5_opr = as_opr(I5);
   277   I6_opr = as_opr(I6);
   278   I7_opr = as_opr(I7);
   280   G0_oop_opr = as_oop_opr(G0);
   281   G1_oop_opr = as_oop_opr(G1);
   282   G2_oop_opr = as_oop_opr(G2);
   283   G3_oop_opr = as_oop_opr(G3);
   284   G4_oop_opr = as_oop_opr(G4);
   285   G5_oop_opr = as_oop_opr(G5);
   286   G6_oop_opr = as_oop_opr(G6);
   287   G7_oop_opr = as_oop_opr(G7);
   288   O0_oop_opr = as_oop_opr(O0);
   289   O1_oop_opr = as_oop_opr(O1);
   290   O2_oop_opr = as_oop_opr(O2);
   291   O3_oop_opr = as_oop_opr(O3);
   292   O4_oop_opr = as_oop_opr(O4);
   293   O5_oop_opr = as_oop_opr(O5);
   294   O6_oop_opr = as_oop_opr(O6);
   295   O7_oop_opr = as_oop_opr(O7);
   296   L0_oop_opr = as_oop_opr(L0);
   297   L1_oop_opr = as_oop_opr(L1);
   298   L2_oop_opr = as_oop_opr(L2);
   299   L3_oop_opr = as_oop_opr(L3);
   300   L4_oop_opr = as_oop_opr(L4);
   301   L5_oop_opr = as_oop_opr(L5);
   302   L6_oop_opr = as_oop_opr(L6);
   303   L7_oop_opr = as_oop_opr(L7);
   304   I0_oop_opr = as_oop_opr(I0);
   305   I1_oop_opr = as_oop_opr(I1);
   306   I2_oop_opr = as_oop_opr(I2);
   307   I3_oop_opr = as_oop_opr(I3);
   308   I4_oop_opr = as_oop_opr(I4);
   309   I5_oop_opr = as_oop_opr(I5);
   310   I6_oop_opr = as_oop_opr(I6);
   311   I7_oop_opr = as_oop_opr(I7);
   313   FP_opr = as_pointer_opr(FP);
   314   SP_opr = as_pointer_opr(SP);
   316   F0_opr = as_float_opr(F0);
   317   F0_double_opr = as_double_opr(F0);
   319   Oexception_opr = as_oop_opr(Oexception);
   320   Oissuing_pc_opr = as_opr(Oissuing_pc);
   322   _caller_save_cpu_regs[0] = FrameMap::O0_opr;
   323   _caller_save_cpu_regs[1] = FrameMap::O1_opr;
   324   _caller_save_cpu_regs[2] = FrameMap::O2_opr;
   325   _caller_save_cpu_regs[3] = FrameMap::O3_opr;
   326   _caller_save_cpu_regs[4] = FrameMap::O4_opr;
   327   _caller_save_cpu_regs[5] = FrameMap::O5_opr;
   328   _caller_save_cpu_regs[6] = FrameMap::G1_opr;
   329   _caller_save_cpu_regs[7] = FrameMap::G3_opr;
   330   _caller_save_cpu_regs[8] = FrameMap::G4_opr;
   331   _caller_save_cpu_regs[9] = FrameMap::G5_opr;
   332   for (int i = 0; i < nof_caller_save_fpu_regs; i++) {
   333     _caller_save_fpu_regs[i] = LIR_OprFact::single_fpu(i);
   334   }
   335 }
   338 Address FrameMap::make_new_address(ByteSize sp_offset) const {
   339   return Address(SP, STACK_BIAS + in_bytes(sp_offset));
   340 }
   343 VMReg FrameMap::fpu_regname (int n) {
   344   return as_FloatRegister(n)->as_VMReg();
   345 }
   348 LIR_Opr FrameMap::stack_pointer() {
   349   return SP_opr;
   350 }
   353 // JSR 292
   354 LIR_Opr FrameMap::method_handle_invoke_SP_save_opr() {
   355   assert(L7 == L7_mh_SP_save, "must be same register");
   356   return L7_opr;
   357 }
   360 bool FrameMap::validate_frame() {
   361   int max_offset = in_bytes(framesize_in_bytes());
   362   int java_index = 0;
   363   for (int i = 0; i < _incoming_arguments->length(); i++) {
   364     LIR_Opr opr = _incoming_arguments->at(i);
   365     if (opr->is_stack()) {
   366       max_offset = MAX2(_argument_locations->at(java_index), max_offset);
   367     }
   368     java_index += type2size[opr->type()];
   369   }
   370   return Assembler::is_simm13(max_offset + STACK_BIAS);
   371 }

mercurial