src/share/vm/c1/c1_CodeStubs.hpp

Wed, 02 Feb 2011 11:35:26 -0500

author
bobv
date
Wed, 02 Feb 2011 11:35:26 -0500
changeset 2508
b92c45f2bc75
parent 2488
e4fee0bdaa85
child 2781
e1162778c1c8
permissions
-rw-r--r--

7016023: Enable building ARM and PPC from src/closed repository
Reviewed-by: dholmes, bdelsart

duke@435 1 /*
never@2488 2 * Copyright (c) 1999, 2011, Oracle and/or its affiliates. All rights reserved.
duke@435 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
duke@435 4 *
duke@435 5 * This code is free software; you can redistribute it and/or modify it
duke@435 6 * under the terms of the GNU General Public License version 2 only, as
duke@435 7 * published by the Free Software Foundation.
duke@435 8 *
duke@435 9 * This code is distributed in the hope that it will be useful, but WITHOUT
duke@435 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
duke@435 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
duke@435 12 * version 2 for more details (a copy is included in the LICENSE file that
duke@435 13 * accompanied this code).
duke@435 14 *
duke@435 15 * You should have received a copy of the GNU General Public License version
duke@435 16 * 2 along with this work; if not, write to the Free Software Foundation,
duke@435 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
duke@435 18 *
trims@1907 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
trims@1907 20 * or visit www.oracle.com if you need additional information or have any
trims@1907 21 * questions.
duke@435 22 *
duke@435 23 */
duke@435 24
stefank@2314 25 #ifndef SHARE_VM_C1_C1_CODESTUBS_HPP
stefank@2314 26 #define SHARE_VM_C1_C1_CODESTUBS_HPP
stefank@2314 27
stefank@2314 28 #include "c1/c1_FrameMap.hpp"
stefank@2314 29 #include "c1/c1_IR.hpp"
stefank@2314 30 #include "c1/c1_Instruction.hpp"
stefank@2314 31 #include "c1/c1_LIR.hpp"
stefank@2314 32 #include "c1/c1_Runtime1.hpp"
stefank@2314 33 #include "utilities/array.hpp"
stefank@2314 34
duke@435 35 class CodeEmitInfo;
duke@435 36 class LIR_Assembler;
duke@435 37 class LIR_OpVisitState;
duke@435 38
duke@435 39 // CodeStubs are little 'out-of-line' pieces of code that
duke@435 40 // usually handle slow cases of operations. All code stubs
duke@435 41 // are collected and code is emitted at the end of the
duke@435 42 // nmethod.
duke@435 43
duke@435 44 class CodeStub: public CompilationResourceObj {
duke@435 45 protected:
duke@435 46 Label _entry; // label at the stub entry point
duke@435 47 Label _continuation; // label where stub continues, if any
duke@435 48
duke@435 49 public:
duke@435 50 CodeStub() {}
duke@435 51
duke@435 52 // code generation
duke@435 53 void assert_no_unbound_labels() { assert(!_entry.is_unbound() && !_continuation.is_unbound(), "unbound label"); }
duke@435 54 virtual void emit_code(LIR_Assembler* e) = 0;
duke@435 55 virtual CodeEmitInfo* info() const { return NULL; }
duke@435 56 virtual bool is_exception_throw_stub() const { return false; }
duke@435 57 virtual bool is_range_check_stub() const { return false; }
duke@435 58 virtual bool is_divbyzero_stub() const { return false; }
duke@435 59 #ifndef PRODUCT
duke@435 60 virtual void print_name(outputStream* out) const = 0;
duke@435 61 #endif
duke@435 62
duke@435 63 // label access
duke@435 64 Label* entry() { return &_entry; }
duke@435 65 Label* continuation() { return &_continuation; }
duke@435 66 // for LIR
duke@435 67 virtual void visit(LIR_OpVisitState* visit) {
duke@435 68 #ifndef PRODUCT
duke@435 69 if (LIRTracePeephole && Verbose) {
duke@435 70 tty->print("no visitor for ");
duke@435 71 print_name(tty);
duke@435 72 tty->cr();
duke@435 73 }
duke@435 74 #endif
duke@435 75 }
duke@435 76 };
duke@435 77
duke@435 78
duke@435 79 define_array(CodeStubArray, CodeStub*)
duke@435 80 define_stack(_CodeStubList, CodeStubArray)
duke@435 81
duke@435 82 class CodeStubList: public _CodeStubList {
duke@435 83 public:
duke@435 84 CodeStubList(): _CodeStubList() {}
duke@435 85
duke@435 86 void append(CodeStub* stub) {
duke@435 87 if (!contains(stub)) {
duke@435 88 _CodeStubList::append(stub);
duke@435 89 }
duke@435 90 }
duke@435 91 };
duke@435 92
duke@435 93 class CounterOverflowStub: public CodeStub {
duke@435 94 private:
duke@435 95 CodeEmitInfo* _info;
duke@435 96 int _bci;
iveresov@2138 97 LIR_Opr _method;
duke@435 98
duke@435 99 public:
iveresov@2138 100 CounterOverflowStub(CodeEmitInfo* info, int bci, LIR_Opr method) : _info(info), _bci(bci), _method(method) {
duke@435 101 }
duke@435 102
duke@435 103 virtual void emit_code(LIR_Assembler* e);
duke@435 104
duke@435 105 virtual void visit(LIR_OpVisitState* visitor) {
duke@435 106 visitor->do_slow_case(_info);
iveresov@2138 107 visitor->do_input(_method);
duke@435 108 }
duke@435 109
duke@435 110 #ifndef PRODUCT
duke@435 111 virtual void print_name(outputStream* out) const { out->print("CounterOverflowStub"); }
duke@435 112 #endif // PRODUCT
duke@435 113
duke@435 114 };
duke@435 115
duke@435 116 class ConversionStub: public CodeStub {
duke@435 117 private:
duke@435 118 Bytecodes::Code _bytecode;
duke@435 119 LIR_Opr _input;
duke@435 120 LIR_Opr _result;
duke@435 121
duke@435 122 static float float_zero;
duke@435 123 static double double_zero;
duke@435 124 public:
duke@435 125 ConversionStub(Bytecodes::Code bytecode, LIR_Opr input, LIR_Opr result)
duke@435 126 : _bytecode(bytecode), _input(input), _result(result) {
duke@435 127 }
duke@435 128
duke@435 129 Bytecodes::Code bytecode() { return _bytecode; }
duke@435 130 LIR_Opr input() { return _input; }
duke@435 131 LIR_Opr result() { return _result; }
duke@435 132
duke@435 133 virtual void emit_code(LIR_Assembler* e);
duke@435 134 virtual void visit(LIR_OpVisitState* visitor) {
duke@435 135 visitor->do_slow_case();
duke@435 136 visitor->do_input(_input);
duke@435 137 visitor->do_output(_result);
duke@435 138 }
duke@435 139 #ifndef PRODUCT
duke@435 140 virtual void print_name(outputStream* out) const { out->print("ConversionStub"); }
duke@435 141 #endif // PRODUCT
duke@435 142 };
duke@435 143
duke@435 144
duke@435 145 // Throws ArrayIndexOutOfBoundsException by default but can be
duke@435 146 // configured to throw IndexOutOfBoundsException in constructor
duke@435 147 class RangeCheckStub: public CodeStub {
duke@435 148 private:
duke@435 149 CodeEmitInfo* _info;
duke@435 150 LIR_Opr _index;
duke@435 151 bool _throw_index_out_of_bounds_exception;
duke@435 152
duke@435 153 public:
duke@435 154 RangeCheckStub(CodeEmitInfo* info, LIR_Opr index, bool throw_index_out_of_bounds_exception = false);
duke@435 155 virtual void emit_code(LIR_Assembler* e);
duke@435 156 virtual CodeEmitInfo* info() const { return _info; }
duke@435 157 virtual bool is_exception_throw_stub() const { return true; }
duke@435 158 virtual bool is_range_check_stub() const { return true; }
duke@435 159 virtual void visit(LIR_OpVisitState* visitor) {
duke@435 160 visitor->do_slow_case(_info);
duke@435 161 visitor->do_input(_index);
duke@435 162 }
duke@435 163 #ifndef PRODUCT
duke@435 164 virtual void print_name(outputStream* out) const { out->print("RangeCheckStub"); }
duke@435 165 #endif // PRODUCT
duke@435 166 };
duke@435 167
duke@435 168
duke@435 169 class DivByZeroStub: public CodeStub {
duke@435 170 private:
duke@435 171 CodeEmitInfo* _info;
duke@435 172 int _offset;
duke@435 173
duke@435 174 public:
duke@435 175 DivByZeroStub(CodeEmitInfo* info)
duke@435 176 : _info(info), _offset(-1) {
duke@435 177 }
duke@435 178 DivByZeroStub(int offset, CodeEmitInfo* info)
duke@435 179 : _info(info), _offset(offset) {
duke@435 180 }
duke@435 181 virtual void emit_code(LIR_Assembler* e);
duke@435 182 virtual CodeEmitInfo* info() const { return _info; }
duke@435 183 virtual bool is_exception_throw_stub() const { return true; }
duke@435 184 virtual bool is_divbyzero_stub() const { return true; }
duke@435 185 virtual void visit(LIR_OpVisitState* visitor) {
duke@435 186 visitor->do_slow_case(_info);
duke@435 187 }
duke@435 188 #ifndef PRODUCT
duke@435 189 virtual void print_name(outputStream* out) const { out->print("DivByZeroStub"); }
duke@435 190 #endif // PRODUCT
duke@435 191 };
duke@435 192
duke@435 193
duke@435 194 class ImplicitNullCheckStub: public CodeStub {
duke@435 195 private:
duke@435 196 CodeEmitInfo* _info;
duke@435 197 int _offset;
duke@435 198
duke@435 199 public:
duke@435 200 ImplicitNullCheckStub(int offset, CodeEmitInfo* info)
duke@435 201 : _offset(offset), _info(info) {
duke@435 202 }
duke@435 203 virtual void emit_code(LIR_Assembler* e);
duke@435 204 virtual CodeEmitInfo* info() const { return _info; }
duke@435 205 virtual bool is_exception_throw_stub() const { return true; }
duke@435 206 virtual void visit(LIR_OpVisitState* visitor) {
duke@435 207 visitor->do_slow_case(_info);
duke@435 208 }
duke@435 209 #ifndef PRODUCT
duke@435 210 virtual void print_name(outputStream* out) const { out->print("ImplicitNullCheckStub"); }
duke@435 211 #endif // PRODUCT
duke@435 212 };
duke@435 213
duke@435 214
duke@435 215 class NewInstanceStub: public CodeStub {
duke@435 216 private:
duke@435 217 ciInstanceKlass* _klass;
duke@435 218 LIR_Opr _klass_reg;
duke@435 219 LIR_Opr _result;
duke@435 220 CodeEmitInfo* _info;
duke@435 221 Runtime1::StubID _stub_id;
duke@435 222
duke@435 223 public:
duke@435 224 NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKlass* klass, CodeEmitInfo* info, Runtime1::StubID stub_id);
duke@435 225 virtual void emit_code(LIR_Assembler* e);
duke@435 226 virtual CodeEmitInfo* info() const { return _info; }
duke@435 227 virtual void visit(LIR_OpVisitState* visitor) {
duke@435 228 visitor->do_slow_case(_info);
duke@435 229 visitor->do_input(_klass_reg);
duke@435 230 visitor->do_output(_result);
duke@435 231 }
duke@435 232 #ifndef PRODUCT
duke@435 233 virtual void print_name(outputStream* out) const { out->print("NewInstanceStub"); }
duke@435 234 #endif // PRODUCT
duke@435 235 };
duke@435 236
duke@435 237
duke@435 238 class NewTypeArrayStub: public CodeStub {
duke@435 239 private:
duke@435 240 LIR_Opr _klass_reg;
duke@435 241 LIR_Opr _length;
duke@435 242 LIR_Opr _result;
duke@435 243 CodeEmitInfo* _info;
duke@435 244
duke@435 245 public:
duke@435 246 NewTypeArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info);
duke@435 247 virtual void emit_code(LIR_Assembler* e);
duke@435 248 virtual CodeEmitInfo* info() const { return _info; }
duke@435 249 virtual void visit(LIR_OpVisitState* visitor) {
duke@435 250 visitor->do_slow_case(_info);
duke@435 251 visitor->do_input(_klass_reg);
duke@435 252 visitor->do_input(_length);
duke@435 253 assert(_result->is_valid(), "must be valid"); visitor->do_output(_result);
duke@435 254 }
duke@435 255 #ifndef PRODUCT
duke@435 256 virtual void print_name(outputStream* out) const { out->print("NewTypeArrayStub"); }
duke@435 257 #endif // PRODUCT
duke@435 258 };
duke@435 259
duke@435 260
duke@435 261 class NewObjectArrayStub: public CodeStub {
duke@435 262 private:
duke@435 263 LIR_Opr _klass_reg;
duke@435 264 LIR_Opr _length;
duke@435 265 LIR_Opr _result;
duke@435 266 CodeEmitInfo* _info;
duke@435 267
duke@435 268 public:
duke@435 269 NewObjectArrayStub(LIR_Opr klass_reg, LIR_Opr length, LIR_Opr result, CodeEmitInfo* info);
duke@435 270 virtual void emit_code(LIR_Assembler* e);
duke@435 271 virtual CodeEmitInfo* info() const { return _info; }
duke@435 272 virtual void visit(LIR_OpVisitState* visitor) {
duke@435 273 visitor->do_slow_case(_info);
duke@435 274 visitor->do_input(_klass_reg);
duke@435 275 visitor->do_input(_length);
duke@435 276 assert(_result->is_valid(), "must be valid"); visitor->do_output(_result);
duke@435 277 }
duke@435 278 #ifndef PRODUCT
duke@435 279 virtual void print_name(outputStream* out) const { out->print("NewObjectArrayStub"); }
duke@435 280 #endif // PRODUCT
duke@435 281 };
duke@435 282
duke@435 283
duke@435 284 class MonitorAccessStub: public CodeStub {
duke@435 285 protected:
duke@435 286 LIR_Opr _obj_reg;
duke@435 287 LIR_Opr _lock_reg;
duke@435 288
duke@435 289 public:
duke@435 290 MonitorAccessStub(LIR_Opr obj_reg, LIR_Opr lock_reg) {
duke@435 291 _obj_reg = obj_reg;
duke@435 292 _lock_reg = lock_reg;
duke@435 293 }
duke@435 294
duke@435 295 #ifndef PRODUCT
duke@435 296 virtual void print_name(outputStream* out) const { out->print("MonitorAccessStub"); }
duke@435 297 #endif // PRODUCT
duke@435 298 };
duke@435 299
duke@435 300
duke@435 301 class MonitorEnterStub: public MonitorAccessStub {
duke@435 302 private:
duke@435 303 CodeEmitInfo* _info;
duke@435 304
duke@435 305 public:
duke@435 306 MonitorEnterStub(LIR_Opr obj_reg, LIR_Opr lock_reg, CodeEmitInfo* info);
duke@435 307
duke@435 308 virtual void emit_code(LIR_Assembler* e);
duke@435 309 virtual CodeEmitInfo* info() const { return _info; }
duke@435 310 virtual void visit(LIR_OpVisitState* visitor) {
duke@435 311 visitor->do_input(_obj_reg);
duke@435 312 visitor->do_input(_lock_reg);
duke@435 313 visitor->do_slow_case(_info);
duke@435 314 }
duke@435 315 #ifndef PRODUCT
duke@435 316 virtual void print_name(outputStream* out) const { out->print("MonitorEnterStub"); }
duke@435 317 #endif // PRODUCT
duke@435 318 };
duke@435 319
duke@435 320
duke@435 321 class MonitorExitStub: public MonitorAccessStub {
duke@435 322 private:
duke@435 323 bool _compute_lock;
duke@435 324 int _monitor_ix;
duke@435 325
duke@435 326 public:
duke@435 327 MonitorExitStub(LIR_Opr lock_reg, bool compute_lock, int monitor_ix)
duke@435 328 : MonitorAccessStub(LIR_OprFact::illegalOpr, lock_reg),
duke@435 329 _compute_lock(compute_lock), _monitor_ix(monitor_ix) { }
duke@435 330 virtual void emit_code(LIR_Assembler* e);
duke@435 331 virtual void visit(LIR_OpVisitState* visitor) {
duke@435 332 assert(_obj_reg->is_illegal(), "unused");
duke@435 333 if (_compute_lock) {
duke@435 334 visitor->do_temp(_lock_reg);
duke@435 335 } else {
duke@435 336 visitor->do_input(_lock_reg);
duke@435 337 }
duke@435 338 }
duke@435 339 #ifndef PRODUCT
duke@435 340 virtual void print_name(outputStream* out) const { out->print("MonitorExitStub"); }
duke@435 341 #endif // PRODUCT
duke@435 342 };
duke@435 343
duke@435 344
duke@435 345 class PatchingStub: public CodeStub {
duke@435 346 public:
duke@435 347 enum PatchID {
duke@435 348 access_field_id,
duke@435 349 load_klass_id
duke@435 350 };
duke@435 351 enum constants {
duke@435 352 patch_info_size = 3
duke@435 353 };
duke@435 354 private:
duke@435 355 PatchID _id;
duke@435 356 address _pc_start;
duke@435 357 int _bytes_to_copy;
duke@435 358 Label _patched_code_entry;
duke@435 359 Label _patch_site_entry;
duke@435 360 Label _patch_site_continuation;
duke@435 361 Register _obj;
duke@435 362 CodeEmitInfo* _info;
duke@435 363 int _oop_index; // index of the patchable oop in nmethod oop table if needed
duke@435 364 static int _patch_info_offset;
duke@435 365
duke@435 366 void align_patch_site(MacroAssembler* masm);
duke@435 367
duke@435 368 public:
duke@435 369 static int patch_info_offset() { return _patch_info_offset; }
duke@435 370
duke@435 371 PatchingStub(MacroAssembler* masm, PatchID id, int oop_index = -1):
duke@435 372 _id(id)
duke@435 373 , _info(NULL)
duke@435 374 , _oop_index(oop_index) {
duke@435 375 if (os::is_MP()) {
duke@435 376 // force alignment of patch sites on MP hardware so we
duke@435 377 // can guarantee atomic writes to the patch site.
duke@435 378 align_patch_site(masm);
duke@435 379 }
duke@435 380 _pc_start = masm->pc();
duke@435 381 masm->bind(_patch_site_entry);
duke@435 382 }
duke@435 383
duke@435 384 void install(MacroAssembler* masm, LIR_PatchCode patch_code, Register obj, CodeEmitInfo* info) {
duke@435 385 _info = info;
duke@435 386 _obj = obj;
duke@435 387 masm->bind(_patch_site_continuation);
duke@435 388 _bytes_to_copy = masm->pc() - pc_start();
duke@435 389 if (_id == PatchingStub::access_field_id) {
duke@435 390 // embed a fixed offset to handle long patches which need to be offset by a word.
duke@435 391 // the patching code will just add the field offset field to this offset so
duke@435 392 // that we can refernce either the high or low word of a double word field.
duke@435 393 int field_offset = 0;
duke@435 394 switch (patch_code) {
duke@435 395 case lir_patch_low: field_offset = lo_word_offset_in_bytes; break;
duke@435 396 case lir_patch_high: field_offset = hi_word_offset_in_bytes; break;
duke@435 397 case lir_patch_normal: field_offset = 0; break;
duke@435 398 default: ShouldNotReachHere();
duke@435 399 }
duke@435 400 NativeMovRegMem* n_move = nativeMovRegMem_at(pc_start());
duke@435 401 n_move->set_offset(field_offset);
duke@435 402 } else if (_id == load_klass_id) {
duke@435 403 assert(_obj != noreg, "must have register object for load_klass");
duke@435 404 #ifdef ASSERT
duke@435 405 // verify that we're pointing at a NativeMovConstReg
duke@435 406 nativeMovConstReg_at(pc_start());
duke@435 407 #endif
duke@435 408 } else {
duke@435 409 ShouldNotReachHere();
duke@435 410 }
duke@435 411 assert(_bytes_to_copy <= (masm->pc() - pc_start()), "not enough bytes");
duke@435 412 }
duke@435 413
duke@435 414 address pc_start() const { return _pc_start; }
duke@435 415 PatchID id() const { return _id; }
duke@435 416
duke@435 417 virtual void emit_code(LIR_Assembler* e);
duke@435 418 virtual CodeEmitInfo* info() const { return _info; }
duke@435 419 virtual void visit(LIR_OpVisitState* visitor) {
duke@435 420 visitor->do_slow_case(_info);
duke@435 421 }
duke@435 422 #ifndef PRODUCT
duke@435 423 virtual void print_name(outputStream* out) const { out->print("PatchingStub"); }
duke@435 424 #endif // PRODUCT
duke@435 425 };
duke@435 426
duke@435 427
twisti@1730 428 //------------------------------------------------------------------------------
twisti@1730 429 // DeoptimizeStub
twisti@1730 430 //
twisti@1730 431 class DeoptimizeStub : public CodeStub {
twisti@1730 432 private:
twisti@1730 433 CodeEmitInfo* _info;
twisti@1730 434
twisti@1730 435 public:
twisti@1730 436 DeoptimizeStub(CodeEmitInfo* info) : _info(new CodeEmitInfo(info)) {}
twisti@1730 437
twisti@1730 438 virtual void emit_code(LIR_Assembler* e);
twisti@1730 439 virtual CodeEmitInfo* info() const { return _info; }
twisti@1730 440 virtual bool is_exception_throw_stub() const { return true; }
twisti@1730 441 virtual void visit(LIR_OpVisitState* visitor) {
twisti@1730 442 visitor->do_slow_case(_info);
twisti@1730 443 }
twisti@1730 444 #ifndef PRODUCT
twisti@1730 445 virtual void print_name(outputStream* out) const { out->print("DeoptimizeStub"); }
twisti@1730 446 #endif // PRODUCT
twisti@1730 447 };
twisti@1730 448
twisti@1730 449
duke@435 450 class SimpleExceptionStub: public CodeStub {
duke@435 451 private:
duke@435 452 LIR_Opr _obj;
duke@435 453 Runtime1::StubID _stub;
duke@435 454 CodeEmitInfo* _info;
duke@435 455
duke@435 456 public:
duke@435 457 SimpleExceptionStub(Runtime1::StubID stub, LIR_Opr obj, CodeEmitInfo* info):
duke@435 458 _obj(obj), _info(info), _stub(stub) {
duke@435 459 }
duke@435 460
bobv@2036 461 void set_obj(LIR_Opr obj) {
bobv@2036 462 _obj = obj;
bobv@2036 463 }
bobv@2036 464
duke@435 465 virtual void emit_code(LIR_Assembler* e);
duke@435 466 virtual CodeEmitInfo* info() const { return _info; }
duke@435 467 virtual bool is_exception_throw_stub() const { return true; }
duke@435 468 virtual void visit(LIR_OpVisitState* visitor) {
duke@435 469 if (_obj->is_valid()) visitor->do_input(_obj);
duke@435 470 visitor->do_slow_case(_info);
duke@435 471 }
duke@435 472 #ifndef PRODUCT
duke@435 473 virtual void print_name(outputStream* out) const { out->print("SimpleExceptionStub"); }
duke@435 474 #endif // PRODUCT
duke@435 475 };
duke@435 476
duke@435 477
duke@435 478
never@2488 479 class ArrayStoreExceptionStub: public SimpleExceptionStub {
duke@435 480 private:
duke@435 481 CodeEmitInfo* _info;
duke@435 482
duke@435 483 public:
never@2488 484 ArrayStoreExceptionStub(LIR_Opr obj, CodeEmitInfo* info): SimpleExceptionStub(Runtime1::throw_array_store_exception_id, obj, info) {}
duke@435 485 #ifndef PRODUCT
duke@435 486 virtual void print_name(outputStream* out) const { out->print("ArrayStoreExceptionStub"); }
duke@435 487 #endif // PRODUCT
duke@435 488 };
duke@435 489
duke@435 490
duke@435 491 class ArrayCopyStub: public CodeStub {
duke@435 492 private:
duke@435 493 LIR_OpArrayCopy* _op;
duke@435 494
duke@435 495 public:
duke@435 496 ArrayCopyStub(LIR_OpArrayCopy* op): _op(op) { }
duke@435 497
duke@435 498 LIR_Opr src() const { return _op->src(); }
duke@435 499 LIR_Opr src_pos() const { return _op->src_pos(); }
duke@435 500 LIR_Opr dst() const { return _op->dst(); }
duke@435 501 LIR_Opr dst_pos() const { return _op->dst_pos(); }
duke@435 502 LIR_Opr length() const { return _op->length(); }
duke@435 503 LIR_Opr tmp() const { return _op->tmp(); }
duke@435 504
duke@435 505 virtual void emit_code(LIR_Assembler* e);
duke@435 506 virtual CodeEmitInfo* info() const { return _op->info(); }
duke@435 507 virtual void visit(LIR_OpVisitState* visitor) {
duke@435 508 // don't pass in the code emit info since it's processed in the fast path
duke@435 509 visitor->do_slow_case();
duke@435 510 }
duke@435 511 #ifndef PRODUCT
duke@435 512 virtual void print_name(outputStream* out) const { out->print("ArrayCopyStub"); }
duke@435 513 #endif // PRODUCT
duke@435 514 };
ysr@777 515
ysr@777 516 //////////////////////////////////////////////////////////////////////////////////////////
ysr@777 517 #ifndef SERIALGC
ysr@777 518
ysr@777 519 // Code stubs for Garbage-First barriers.
ysr@777 520 class G1PreBarrierStub: public CodeStub {
ysr@777 521 private:
ysr@777 522 LIR_Opr _addr;
ysr@777 523 LIR_Opr _pre_val;
ysr@777 524 LIR_PatchCode _patch_code;
ysr@777 525 CodeEmitInfo* _info;
ysr@777 526
ysr@777 527 public:
ysr@777 528 // pre_val (a temporary register) must be a register;
ysr@777 529 // addr (the address of the field to be read) must be a LIR_Address
ysr@777 530 G1PreBarrierStub(LIR_Opr addr, LIR_Opr pre_val, LIR_PatchCode patch_code, CodeEmitInfo* info) :
ysr@777 531 _addr(addr), _pre_val(pre_val), _patch_code(patch_code), _info(info)
ysr@777 532 {
ysr@777 533 assert(_pre_val->is_register(), "should be temporary register");
ysr@777 534 assert(_addr->is_address(), "should be the address of the field");
ysr@777 535 }
ysr@777 536
ysr@777 537 LIR_Opr addr() const { return _addr; }
ysr@777 538 LIR_Opr pre_val() const { return _pre_val; }
ysr@777 539 LIR_PatchCode patch_code() const { return _patch_code; }
ysr@777 540 CodeEmitInfo* info() const { return _info; }
ysr@777 541
ysr@777 542 virtual void emit_code(LIR_Assembler* e);
ysr@777 543 virtual void visit(LIR_OpVisitState* visitor) {
ysr@777 544 // don't pass in the code emit info since it's processed in the fast
ysr@777 545 // path
ysr@777 546 if (_info != NULL)
ysr@777 547 visitor->do_slow_case(_info);
ysr@777 548 else
ysr@777 549 visitor->do_slow_case();
ysr@777 550 visitor->do_input(_addr);
ysr@777 551 visitor->do_temp(_pre_val);
ysr@777 552 }
ysr@777 553 #ifndef PRODUCT
ysr@777 554 virtual void print_name(outputStream* out) const { out->print("G1PreBarrierStub"); }
ysr@777 555 #endif // PRODUCT
ysr@777 556 };
ysr@777 557
ysr@777 558 class G1PostBarrierStub: public CodeStub {
ysr@777 559 private:
ysr@777 560 LIR_Opr _addr;
ysr@777 561 LIR_Opr _new_val;
ysr@777 562
ysr@777 563 static jbyte* _byte_map_base;
ysr@777 564 static jbyte* byte_map_base_slow();
ysr@777 565 static jbyte* byte_map_base() {
ysr@777 566 if (_byte_map_base == NULL) {
ysr@777 567 _byte_map_base = byte_map_base_slow();
ysr@777 568 }
ysr@777 569 return _byte_map_base;
ysr@777 570 }
ysr@777 571
ysr@777 572 public:
ysr@777 573 // addr (the address of the object head) and new_val must be registers.
ysr@777 574 G1PostBarrierStub(LIR_Opr addr, LIR_Opr new_val): _addr(addr), _new_val(new_val) { }
ysr@777 575
ysr@777 576 LIR_Opr addr() const { return _addr; }
ysr@777 577 LIR_Opr new_val() const { return _new_val; }
ysr@777 578
ysr@777 579 virtual void emit_code(LIR_Assembler* e);
ysr@777 580 virtual void visit(LIR_OpVisitState* visitor) {
ysr@777 581 // don't pass in the code emit info since it's processed in the fast path
ysr@777 582 visitor->do_slow_case();
ysr@777 583 visitor->do_input(_addr);
ysr@777 584 visitor->do_input(_new_val);
ysr@777 585 }
ysr@777 586 #ifndef PRODUCT
ysr@777 587 virtual void print_name(outputStream* out) const { out->print("G1PostBarrierStub"); }
ysr@777 588 #endif // PRODUCT
ysr@777 589 };
ysr@777 590
ysr@777 591 #endif // SERIALGC
ysr@777 592 //////////////////////////////////////////////////////////////////////////////////////////
stefank@2314 593
stefank@2314 594 #endif // SHARE_VM_C1_C1_CODESTUBS_HPP

mercurial