src/share/vm/c1/c1_CodeStubs.hpp

Mon, 12 Aug 2019 18:30:40 +0300

author
apetushkov
date
Mon, 12 Aug 2019 18:30:40 +0300
changeset 9858
b985cbb00e68
parent 8739
0b85ccd62409
child 8856
ac27a9c85bea
permissions
-rw-r--r--

8223147: JFR Backport
8199712: Flight Recorder
8203346: JFR: Inconsistent signature of jfr_add_string_constant
8195817: JFR.stop should require name of recording
8195818: JFR.start should increase autogenerated name by one
8195819: Remove recording=x from jcmd JFR.check output
8203921: JFR thread sampling is missing fixes from JDK-8194552
8203929: Limit amount of data for JFR.dump
8203664: JFR start failure after AppCDS archive created with JFR StartFlightRecording
8003209: JFR events for network utilization
8207392: [PPC64] Implement JFR profiling
8202835: jfr/event/os/TestSystemProcess.java fails on missing events
Summary: Backport JFR from JDK11. Initial integration
Reviewed-by: neugens

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

mercurial