src/share/vm/c1/c1_CodeStubs.hpp

Thu, 10 Oct 2013 15:44:12 +0200

author
anoll
date
Thu, 10 Oct 2013 15:44:12 +0200
changeset 5919
469216acdb28
parent 5628
f98f5d48f511
child 6198
55fb97c4c58d
permissions
-rw-r--r--

8023014: CodeSweeperSweepNoFlushTest.java fails with HS crash
Summary: Ensure ensure correct initialization of compiler runtime
Reviewed-by: kvn, twisti

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

mercurial