1 /*
   2  * Copyright (c) 1999, 2007, Oracle and/or its affiliates. All rights reserved.
   3  * Copyright 2008, 2009 Red Hat, Inc.
   4  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   5  *
   6  * This code is free software; you can redistribute it and/or modify it
   7  * under the terms of the GNU General Public License version 2 only, as
   8  * published by the Free Software Foundation.
   9  *
  10  * This code is distributed in the hope that it will be useful, but WITHOUT
  11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  13  * version 2 for more details (a copy is included in the LICENSE file that
  14  * accompanied this code).
  15  *
  16  * You should have received a copy of the GNU General Public License version
  17  * 2 along with this work; if not, write to the Free Software Foundation,
  18  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  19  *
  20  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  21  * or visit www.oracle.com if you need additional information or have any
  22  * questions.
  23  *
  24  */
  25 
  26 #include "incls/_precompiled.incl"
  27 #include "incls/_sharkCacheDecache.cpp.incl"
  28 
  29 using namespace llvm;
  30 
  31 void SharkDecacher::start_frame() {
  32   // Start recording the debug information
  33   _pc_offset = code_buffer()->create_unique_offset();
  34   _oopmap = new OopMap(
  35     oopmap_slot_munge(stack()->oopmap_frame_size()),
  36     oopmap_slot_munge(arg_size()));
  37   debug_info()->add_safepoint(pc_offset(), oopmap());
  38 }
  39 
  40 void SharkDecacher::start_stack(int stack_depth) {
  41   // Create the array we'll record our stack slots in
  42   _exparray = new GrowableArray<ScopeValue*>(stack_depth);
  43 
  44   // Set the stack pointer
  45   stack()->CreateStoreStackPointer(
  46     builder()->CreatePtrToInt(
  47       stack()->slot_addr(
  48         stack()->stack_slots_offset() + max_stack() - stack_depth),
  49       SharkType::intptr_type()));
  50 }
  51 
  52 void SharkDecacher::process_stack_slot(int          index,
  53                                        SharkValue** addr,
  54                                        int          offset) {
  55   SharkValue *value = *addr;
  56 
  57   // Write the value to the frame if necessary
  58   if (stack_slot_needs_write(index, value)) {
  59     write_value_to_frame(
  60       SharkType::to_stackType(value->basic_type()),
  61       value->generic_value(),
  62       adjusted_offset(value, offset));
  63   }
  64 
  65   // Record the value in the oopmap if necessary
  66   if (stack_slot_needs_oopmap(index, value)) {
  67     oopmap()->set_oop(slot2reg(offset));
  68   }
  69 
  70   // Record the value in the debuginfo if necessary
  71   if (stack_slot_needs_debuginfo(index, value)) {
  72     exparray()->append(slot2lv(offset, stack_location_type(index, addr)));
  73   }
  74 }
  75 
  76 void SharkDecacher::start_monitors(int num_monitors) {
  77   // Create the array we'll record our monitors in
  78   _monarray = new GrowableArray<MonitorValue*>(num_monitors);
  79 }
  80 
  81 void SharkDecacher::process_monitor(int index, int box_offset, int obj_offset) {
  82   oopmap()->set_oop(slot2reg(obj_offset));
  83 
  84   monarray()->append(new MonitorValue(
  85     slot2lv (obj_offset, Location::oop),
  86     slot2loc(box_offset, Location::normal)));
  87 }
  88 
  89 void SharkDecacher::process_oop_tmp_slot(Value** value, int offset) {
  90   // Decache the temporary oop slot
  91   if (*value) {
  92     write_value_to_frame(
  93       SharkType::oop_type(),
  94       *value,
  95       offset);
  96 
  97     oopmap()->set_oop(slot2reg(offset));
  98   }
  99 }
 100 
 101 void SharkDecacher::process_method_slot(Value** value, int offset) {
 102   // Decache the method pointer
 103   write_value_to_frame(
 104     SharkType::methodOop_type(),
 105     *value,
 106     offset);
 107 
 108   oopmap()->set_oop(slot2reg(offset));
 109 }
 110 
 111 void SharkDecacher::process_pc_slot(int offset) {
 112   // Record the PC
 113   builder()->CreateStore(
 114     builder()->code_buffer_address(pc_offset()),
 115     stack()->slot_addr(offset));
 116 }
 117 
 118 void SharkDecacher::start_locals() {
 119   // Create the array we'll record our local variables in
 120   _locarray = new GrowableArray<ScopeValue*>(max_locals());}
 121 
 122 void SharkDecacher::process_local_slot(int          index,
 123                                        SharkValue** addr,
 124                                        int          offset) {
 125   SharkValue *value = *addr;
 126 
 127   // Write the value to the frame if necessary
 128   if (local_slot_needs_write(index, value)) {
 129     write_value_to_frame(
 130       SharkType::to_stackType(value->basic_type()),
 131       value->generic_value(),
 132       adjusted_offset(value, offset));
 133   }
 134 
 135   // Record the value in the oopmap if necessary
 136   if (local_slot_needs_oopmap(index, value)) {
 137     oopmap()->set_oop(slot2reg(offset));
 138   }
 139 
 140   // Record the value in the debuginfo if necessary
 141   if (local_slot_needs_debuginfo(index, value)) {
 142     locarray()->append(slot2lv(offset, local_location_type(index, addr)));
 143   }
 144 }
 145 
 146 void SharkDecacher::end_frame() {
 147   // Record the scope
 148   debug_info()->describe_scope(
 149     pc_offset(),
 150     target(),
 151     bci(),
 152     true,
 153     false,
 154     false,
 155     debug_info()->create_scope_values(locarray()),
 156     debug_info()->create_scope_values(exparray()),
 157     debug_info()->create_monitor_values(monarray()));
 158 
 159   // Finish recording the debug information
 160   debug_info()->end_safepoint(pc_offset());
 161 }
 162 
 163 void SharkCacher::process_stack_slot(int          index,
 164                                      SharkValue** addr,
 165                                      int          offset) {
 166   SharkValue *value = *addr;
 167 
 168   // Read the value from the frame if necessary
 169   if (stack_slot_needs_read(index, value)) {
 170     *addr = SharkValue::create_generic(
 171       value->type(),
 172       read_value_from_frame(
 173         SharkType::to_stackType(value->basic_type()),
 174         adjusted_offset(value, offset)),
 175       value->zero_checked());
 176   }
 177 }
 178 
 179 void SharkOSREntryCacher::process_monitor(int index,
 180                                           int box_offset,
 181                                           int obj_offset) {
 182   // Copy the monitor from the OSR buffer to the frame
 183   int src_offset = max_locals() + index * 2;
 184   builder()->CreateStore(
 185     builder()->CreateLoad(
 186       CreateAddressOfOSRBufEntry(src_offset, SharkType::intptr_type())),
 187     stack()->slot_addr(box_offset, SharkType::intptr_type()));
 188   builder()->CreateStore(
 189     builder()->CreateLoad(
 190       CreateAddressOfOSRBufEntry(src_offset + 1, SharkType::oop_type())),
 191     stack()->slot_addr(obj_offset, SharkType::oop_type()));
 192 }
 193 
 194 void SharkCacher::process_oop_tmp_slot(Value** value, int offset) {
 195   // Cache the temporary oop
 196   if (*value)
 197     *value = read_value_from_frame(SharkType::oop_type(), offset);
 198 }
 199 
 200 void SharkCacher::process_method_slot(Value** value, int offset) {
 201   // Cache the method pointer
 202   *value = read_value_from_frame(SharkType::methodOop_type(), offset);
 203 }
 204 
 205 void SharkFunctionEntryCacher::process_method_slot(Value** value, int offset) {
 206   // "Cache" the method pointer
 207   *value = method();
 208 }
 209 
 210 void SharkCacher::process_local_slot(int          index,
 211                                      SharkValue** addr,
 212                                      int          offset) {
 213   SharkValue *value = *addr;
 214 
 215   // Read the value from the frame if necessary
 216   if (local_slot_needs_read(index, value)) {
 217     *addr = SharkValue::create_generic(
 218       value->type(),
 219       read_value_from_frame(
 220         SharkType::to_stackType(value->basic_type()),
 221         adjusted_offset(value, offset)),
 222       value->zero_checked());
 223   }
 224 }
 225 
 226 Value* SharkOSREntryCacher::CreateAddressOfOSRBufEntry(int         offset,
 227                                                        const Type* type) {
 228   Value *result = builder()->CreateStructGEP(osr_buf(), offset);
 229   if (type != SharkType::intptr_type())
 230     result = builder()->CreateBitCast(result, PointerType::getUnqual(type));
 231   return result;
 232 }
 233 
 234 void SharkOSREntryCacher::process_local_slot(int          index,
 235                                              SharkValue** addr,
 236                                              int          offset) {
 237   SharkValue *value = *addr;
 238 
 239   // Read the value from the OSR buffer if necessary
 240   if (local_slot_needs_read(index, value)) {
 241     *addr = SharkValue::create_generic(
 242       value->type(),
 243       builder()->CreateLoad(
 244         CreateAddressOfOSRBufEntry(
 245           adjusted_offset(value, max_locals() - 1 - index),
 246           SharkType::to_stackType(value->basic_type()))),
 247       value->zero_checked());
 248   }
 249 }
 250 
 251 void SharkDecacher::write_value_to_frame(const Type* type,
 252                                          Value*      value,
 253                                          int         offset) {
 254   builder()->CreateStore(value, stack()->slot_addr(offset, type));
 255 }
 256 
 257 Value* SharkCacher::read_value_from_frame(const Type* type, int offset) {
 258   return builder()->CreateLoad(stack()->slot_addr(offset, type));
 259 }