src/share/vm/opto/machnode.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File
*** old/src/share/vm/opto/machnode.cpp Fri Nov 12 05:56:56 2010
--- new/src/share/vm/opto/machnode.cpp Fri Nov 12 05:56:55 2010
*** 1,7 ****
--- 1,7 ----
/*
! * Copyright (c) 1997, 2009, Oracle and/or its affiliates. All rights reserved.
! * Copyright (c) 1997, 2010, Oracle and/or its affiliates. All rights reserved.
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
*
* This code is free software; you can redistribute it and/or modify it
* under the terms of the GNU General Public License version 2 only, as
* published by the Free Software Foundation.
*** 485,494 ****
--- 485,693 ----
void MachTypeNode::dump_spec(outputStream *st) const {
_bottom_type->dump_on(st);
}
#endif
+
+ //=============================================================================
+ // Two Constant's are equal when the type and the value are equal.
+ bool MachConstantBaseNode::Constant::operator==(const Constant& other) {
+ if (type() != other.type() ) return false;
+ if (can_be_reused() != other.can_be_reused()) return false;
+ // For floating point values we compare the bit pattern.
+ switch (type()) {
+ case T_FLOAT: return (_value.i == other._value.i);
+ case T_LONG:
+ case T_DOUBLE: return (_value.j == other._value.j);
+ case T_OBJECT:
+ case T_ADDRESS: return (_value.l == other._value.l);
+ case T_VOID: return (_value.l == other._value.l); // jump-table entries
+ default: ShouldNotReachHere();
+ }
+ return false;
+ }
+
+ int MachConstantBaseNode::add_constant(Constant& con) {
+ if (con.can_be_reused()) {
+ int idx = _constants.find(con);
+ if (idx != -1 && _constants.at(idx).can_be_reused()) {
+ return idx;
+ }
+ }
+ int idx = _constants.append(con);
+ return idx;
+ }
+
+ // Emit constants grouped in the following order:
+ static BasicType type_order[] = {
+ T_FLOAT, // 32-bit
+ T_OBJECT, // 32 or 64-bit
+ T_ADDRESS, // 32 or 64-bit
+ T_DOUBLE, // 64-bit
+ T_LONG, // 64-bit
+ T_VOID, // 32 or 64-bit (jump-tables are at the end of the constant table for code emission reasons)
+ T_ILLEGAL
+ };
+
+ static int type_to_size_in_bytes(BasicType t) {
+ switch (t) {
+ case T_LONG: return sizeof(jlong );
+ case T_FLOAT: return sizeof(jfloat );
+ case T_DOUBLE: return sizeof(jdouble);
+ // We use T_VOID as marker for jump-table entries (labels) which
+ // need an interal word relocation.
+ case T_VOID:
+ case T_ADDRESS:
+ case T_OBJECT: return sizeof(jobject);
+ }
+
+ ShouldNotReachHere();
+ return -1;
+ }
+
+ int MachConstantBaseNode::calculate_constant_table_size() {
+ int size = 0;
+ for (int t = 0; type_order[t] != T_ILLEGAL; t++) {
+ BasicType type = type_order[t];
+
+ for (int i = 0; i < _constants.length(); i++) {
+ Constant con = _constants.at(i);
+ if (con.type() != type) continue; // Skip other types.
+
+ // Align size for type and add type size;
+ int typesize = type_to_size_in_bytes(con.type());
+ size = align_size_up(size, typesize) + typesize;
+ }
+ }
+
+ // Align up to the next section start, which is insts (see
+ // CodeBuffer::align_at_start).
+ return align_size_up(size, CodeEntryAlignment);
+ }
+
+ void MachConstantBaseNode::emit_constant_table(CodeBuffer& cb) {
+ MacroAssembler _masm(&cb);
+ for (int t = 0; type_order[t] != T_ILLEGAL; t++) {
+ BasicType type = type_order[t];
+
+ for (int i = 0; i < _constants.length(); i++) {
+ Constant con = _constants.at(i);
+ if (con.type() != type) continue; // Skip other types.
+
+ address constant_addr;
+ switch (con.type()) {
+ case T_LONG: constant_addr = _masm.long_constant( con.get_jlong() ); break;
+ case T_FLOAT: constant_addr = _masm.float_constant( con.get_jfloat() ); break;
+ case T_DOUBLE: constant_addr = _masm.double_constant(con.get_jdouble()); break;
+ case T_OBJECT: {
+ jobject obj = con.get_jobject();
+ int oop_index = _masm.oop_recorder()->find_index(obj);
+ constant_addr = _masm.address_constant((address) obj, oop_Relocation::spec(oop_index));
+ break;
+ }
+ case T_ADDRESS: {
+ address addr = (address) con.get_jobject();
+ constant_addr = _masm.address_constant(addr);
+ break;
+ }
+ // We use T_VOID as marker for jump-table entries (labels) which
+ // need an interal word relocation.
+ case T_VOID: {
+ // Write a dummy word. The real value is filled in later
+ // in fill_jump_table_in_constant_table.
+ address addr = (address) con.get_jobject();
+ constant_addr = _masm.address_constant(addr);
+ break;
+ }
+ default: ShouldNotReachHere();
+ }
+ assert(constant_addr != NULL, "consts section too small");
+ con.set_offset(constant_addr - _masm.code()->consts()->start());
+ _constants.at_put(i, con);
+ }
+ }
+ }
+
+ int MachConstantBaseNode::find_constant_offset(Constant& con) const {
+ int idx = _constants.find(con);
+ assert(idx != -1, "constant must be in constant table");
+ int offset = _constants.at(idx).offset();
+ return offset;
+ }
+
+
+ //=============================================================================
+ void MachConstantNode::add_to_constant_table(BasicType type, jvalue value) {
+ MachConstantBaseNode* base = Compile::current()->mach_constant_base_node();
+ _constant = MachConstantBaseNode::Constant(type, value);
+ (void) base->add_constant(_constant);
+ }
+
+ void MachConstantNode::add_to_constant_table(MachOper* oper) {
+ jvalue value;
+ BasicType type = oper->type()->basic_type();
+ switch (type) {
+ case T_LONG: value.j = oper->constantL(); break;
+ case T_FLOAT: value.f = oper->constantF(); break;
+ case T_DOUBLE: value.d = oper->constantD(); break;
+ case T_OBJECT:
+ case T_ADDRESS: value.l = (jobject) oper->constant(); break;
+ default: ShouldNotReachHere();
+ }
+ add_to_constant_table(type, value);
+ }
+
+ void MachConstantNode::allocate_jump_table_in_constant_table() {
+ MachConstantBaseNode* base = Compile::current()->mach_constant_base_node();
+ jvalue value;
+ // We can use the 'this' pointer here to identify the right jump-table
+ // as this method is called from Compile::Fill_buffer right before
+ // the MachNodes are emitted and the table is filled (means the
+ // MachNode pointers do not change anymore).
+ value.l = (jobject) this;
+ _constant = MachConstantBaseNode::Constant(T_VOID, value, false); // Labels of a jump-table cannot be reused.
+ for (uint i = 0; i < outcnt(); i++) {
+ (void) base->add_constant(_constant);
+ }
+ }
+
+ void MachConstantNode::fill_jump_table_in_constant_table(CodeBuffer& cb, GrowableArray<Label*> labels) const {
+ // If called from Compile::scratch_emit_size do nothing.
+ if (Compile::current()->in_scratch_emit_size()) return;
+
+ assert(labels.is_nonempty(), "must be");
+ assert((uint) labels.length() == outcnt(), err_msg("must be equal: %d == %d", labels.length(), outcnt()));
+
+ // Since constant_offset() also contains table_base_offset() we need
+ // to subtract the table_base_offset() to get the plain offset into
+ // the constant table.
+ MachConstantBaseNode* base = Compile::current()->mach_constant_base_node();
+ int offset = constant_offset() - base->table_base_offset();
+
+ MacroAssembler _masm(&cb);
+ address* jump_table_base = (address*) (_masm.code()->consts()->start() + offset);
+
+ for (int i = 0; i < labels.length(); i++) {
+ address* constant_addr = &jump_table_base[i];
+ assert(*constant_addr == (address) this, "all jump-table entries must contain 'this' value");
+ *constant_addr = cb.consts()->target(*labels.at(i), (address) constant_addr);
+ cb.consts()->relocate((address) constant_addr, relocInfo::internal_word_type);
+ }
+ }
+
+ int MachConstantNode::constant_offset() {
+ int offset = _constant.offset();
+ // Bind the offset lazily.
+ if (offset == -1) {
+ MachConstantBaseNode* base = Compile::current()->mach_constant_base_node();
+ offset = base->table_base_offset() + base->find_constant_offset(_constant);
+ _constant.set_offset(offset);
+ }
+ return offset;
+ }
+
+
//=============================================================================
#ifndef PRODUCT
void MachNullCheckNode::format( PhaseRegAlloc *ra_, outputStream *st ) const {
int reg = ra_->get_reg_first(in(1)->in(_vidx));
tty->print("%s %s", Name(), Matcher::regName[reg]);
src/share/vm/opto/machnode.cpp
Index
Unified diffs
Context diffs
Sdiffs
Wdiffs
Patch
New
Old
Previous File
Next File