/*
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*
* This code is distributed in the hope that it will be useful, but WITHOUT
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* version 2 for more details (a copy is included in the LICENSE file that
* accompanied this code).
*
* You should have received a copy of the GNU General Public License version
* 2 along with this work; if not, write to the Free Software Foundation,
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
*
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
* or visit www.oracle.com if you need additional information or have any
* questions.
*
*/
#ifndef SHARE_VM_C1_C1_CODESTUBS_HPP
#define SHARE_VM_C1_C1_CODESTUBS_HPP
#include "c1/c1_FrameMap.hpp"
#include "c1/c1_Instruction.hpp"
#include "c1/c1_LIR.hpp"
#include "c1/c1_Runtime1.hpp"
class CodeEmitInfo;
class LIR_Assembler;
class LIR_OpVisitState;
// CodeStubs are little 'out-of-line' pieces of code that
// usually handle slow cases of operations. All code stubs
// are collected and code is emitted at the end of the
// nmethod.
protected:
public:
CodeStub() {}
// code generation
void assert_no_unbound_labels() { assert(!_entry.is_unbound() && !_continuation.is_unbound(), "unbound label"); }
virtual void emit_code(LIR_Assembler* e) = 0;
virtual bool is_exception_throw_stub() const { return false; }
virtual bool is_range_check_stub() const { return false; }
virtual bool is_divbyzero_stub() const { return false; }
#ifndef PRODUCT
#endif
// label access
// for LIR
#ifndef PRODUCT
if (LIRTracePeephole && Verbose) {
}
#endif
}
};
public:
}
}
};
private:
int _bci;
public:
CounterOverflowStub(CodeEmitInfo* info, int bci, LIR_Opr method) : _info(info), _bci(bci), _method(method) {
}
virtual void emit_code(LIR_Assembler* e);
}
#ifndef PRODUCT
#endif // PRODUCT
};
private:
static float float_zero;
static double double_zero;
public:
}
virtual void emit_code(LIR_Assembler* e);
visitor->do_slow_case();
}
#ifndef PRODUCT
#endif // PRODUCT
};
// Throws ArrayIndexOutOfBoundsException by default but can be
// configured to throw IndexOutOfBoundsException in constructor
private:
public:
RangeCheckStub(CodeEmitInfo* info, LIR_Opr index, bool throw_index_out_of_bounds_exception = false);
virtual void emit_code(LIR_Assembler* e);
virtual bool is_exception_throw_stub() const { return true; }
virtual bool is_range_check_stub() const { return true; }
}
#ifndef PRODUCT
#endif // PRODUCT
};
private:
int _offset;
public:
}
}
virtual void emit_code(LIR_Assembler* e);
virtual bool is_exception_throw_stub() const { return true; }
virtual bool is_divbyzero_stub() const { return true; }
}
#ifndef PRODUCT
#endif // PRODUCT
};
private:
int _offset;
public:
}
virtual void emit_code(LIR_Assembler* e);
virtual bool is_exception_throw_stub() const { return true; }
}
#ifndef PRODUCT
#endif // PRODUCT
};
private:
public:
NewInstanceStub(LIR_Opr klass_reg, LIR_Opr result, ciInstanceKlass* klass, CodeEmitInfo* info, Runtime1::StubID stub_id);
virtual void emit_code(LIR_Assembler* e);
}
#ifndef PRODUCT
#endif // PRODUCT
};
private:
public:
virtual void emit_code(LIR_Assembler* e);
}
#ifndef PRODUCT
#endif // PRODUCT
};
private:
public:
virtual void emit_code(LIR_Assembler* e);
}
#ifndef PRODUCT
#endif // PRODUCT
};
protected:
public:
}
#ifndef PRODUCT
#endif // PRODUCT
};
private:
public:
virtual void emit_code(LIR_Assembler* e);
}
#ifndef PRODUCT
#endif // PRODUCT
};
private:
bool _compute_lock;
int _monitor_ix;
public:
virtual void emit_code(LIR_Assembler* e);
if (_compute_lock) {
} else {
}
}
#ifndef PRODUCT
#endif // PRODUCT
};
public:
enum PatchID {
};
enum constants {
};
private:
int _bytes_to_copy;
static int _patch_info_offset;
public:
, _oop_index(oop_index) {
// force alignment of patch sites on MP hardware so we
// can guarantee atomic writes to the patch site.
}
}
// embed a fixed offset to handle long patches which need to be offset by a word.
// the patching code will just add the field offset field to this offset so
// that we can refernce either the high or low word of a double word field.
int field_offset = 0;
switch (patch_code) {
case lir_patch_normal: field_offset = 0; break;
default: ShouldNotReachHere();
}
} else if (_id == load_klass_id) {
#ifdef ASSERT
// verify that we're pointing at a NativeMovConstReg
#endif
} else {
}
}
virtual void emit_code(LIR_Assembler* e);
}
#ifndef PRODUCT
#endif // PRODUCT
};
//------------------------------------------------------------------------------
// DeoptimizeStub
//
private:
public:
virtual void emit_code(LIR_Assembler* e);
virtual bool is_exception_throw_stub() const { return true; }
}
#ifndef PRODUCT
#endif // PRODUCT
};
private:
public:
}
}
virtual void emit_code(LIR_Assembler* e);
virtual bool is_exception_throw_stub() const { return true; }
}
#ifndef PRODUCT
#endif // PRODUCT
};
private:
public:
ArrayStoreExceptionStub(LIR_Opr obj, CodeEmitInfo* info): SimpleExceptionStub(Runtime1::throw_array_store_exception_id, obj, info) {}
#ifndef PRODUCT
#endif // PRODUCT
};
private:
public:
virtual void emit_code(LIR_Assembler* e);
// don't pass in the code emit info since it's processed in the fast path
visitor->do_slow_case();
}
#ifndef PRODUCT
#endif // PRODUCT
};
//////////////////////////////////////////////////////////////////////////////////////////
#ifndef SERIALGC
// Code stubs for Garbage-First barriers.
private:
bool _do_load;
public:
// Version that _does_ generate a load of the previous value from addr.
// addr (the address of the field to be read) must be a LIR_Address
// pre_val (a temporary register) must be a register;
{
}
// Version that _does not_ generate load of the previous value; the
// previous value is assumed to have already been loaded into pre_val.
{
}
virtual void emit_code(LIR_Assembler* e);
if (_do_load) {
// don't pass in the code emit info since it's processed in the fast
// path
else
visitor->do_slow_case();
} else {
visitor->do_slow_case();
}
}
#ifndef PRODUCT
#endif // PRODUCT
};
private:
static jbyte* byte_map_base_slow();
if (_byte_map_base == NULL) {
}
return _byte_map_base;
}
public:
// addr (the address of the object head) and new_val must be registers.
virtual void emit_code(LIR_Assembler* e);
// don't pass in the code emit info since it's processed in the fast path
visitor->do_slow_case();
}
#ifndef PRODUCT
#endif // PRODUCT
};
#endif // SERIALGC
//////////////////////////////////////////////////////////////////////////////////////////
#endif // SHARE_VM_C1_C1_CODESTUBS_HPP