--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/Location.java Thu Sep 11 11:25:43 2008 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/code/Location.java Wed Sep 17 18:02:38 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2005 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-2008 Sun Microsystems, Inc. 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
@@ -39,9 +39,9 @@
<P> Encoding: </P>
<PRE>
bits:
- Where: [15]
- Type: [14..12]
- Offset: [11..0]
+ Type: [3..0]
+ Where: [4]
+ Offset: [31..5]
</PRE>
*/
@@ -69,6 +69,7 @@
// Location::Type constants
TYPE_NORMAL = db.lookupIntConstant("Location::normal").intValue();
TYPE_OOP = db.lookupIntConstant("Location::oop").intValue();
+ TYPE_NARROWOOP = db.lookupIntConstant("Location::narrowoop").intValue();
TYPE_INT_IN_LONG = db.lookupIntConstant("Location::int_in_long").intValue();
TYPE_LNG = db.lookupIntConstant("Location::lng").intValue();
TYPE_FLOAT_IN_DBL = db.lookupIntConstant("Location::float_in_dbl").intValue();
@@ -115,6 +116,8 @@
public static final Type NORMAL = new Type("normal");
/** Oop (please GC me!) */
public static final Type OOP = new Type("oop");
+ /** NarrowOop (please GC me!) */
+ public static final Type NARROWOOP = new Type("narrowoop");
/** Long held in one register */
public static final Type INT_IN_LONG = new Type("int_in_long");
/** Long held in one register */
@@ -142,6 +145,8 @@
return TYPE_NORMAL;
} else if (this == OOP) {
return TYPE_OOP;
+ } else if (this == NARROWOOP) {
+ return TYPE_NARROWOOP;
} else if (this == INT_IN_LONG) {
return TYPE_INT_IN_LONG;
} else if (this == LNG) {
@@ -170,6 +175,7 @@
// constants in Type enum
private static int TYPE_NORMAL;
private static int TYPE_OOP;
+ private static int TYPE_NARROWOOP;
private static int TYPE_INT_IN_LONG;
private static int TYPE_LNG;
private static int TYPE_FLOAT_IN_DBL;
@@ -185,7 +191,7 @@
Location(Where where, Type type, int offset) {
setWhere(where);
setType(type);
- setOffset(offset & 0x0000FFFF);
+ setOffset(offset);
}
public Where getWhere() {
@@ -205,6 +211,8 @@
return Type.NORMAL;
} else if (type == TYPE_OOP) {
return Type.OOP;
+ } else if (type == TYPE_NARROWOOP) {
+ return Type.NARROWOOP;
} else if (type == TYPE_INT_IN_LONG) {
return Type.INT_IN_LONG;
} else if (type == TYPE_LNG) {
@@ -238,6 +246,10 @@
return getType() == Type.OOP;
}
+ public boolean holdsNarrowOop() {
+ return getType() == Type.NARROWOOP;
+ }
+
public boolean holdsInt() {
return getType() == Type.INT_IN_LONG;
}
@@ -266,7 +278,7 @@
if (Assert.ASSERTS_ENABLED) {
Assert.that(getWhere() == Where.ON_STACK, "wrong Where");
}
- return getOffset() << VM.getVM().getLogAddressSize();
+ return getOffset() * (int)VM.getVM().getIntSize();
}
public int getRegisterNumber() {
@@ -296,6 +308,8 @@
if (type == Type.NORMAL) {
} else if (type == Type.OOP) {
tty.print(",oop");
+ } else if (type == Type.NARROWOOP) {
+ tty.print(",narrowoop");
} else if (type == Type.INT_IN_LONG) {
tty.print(",int");
} else if (type == Type.LNG) {
@@ -314,26 +328,26 @@
/** Serialization of debugging information */
public Location(DebugInfoReadStream stream) {
- value = (0x0000FFFF & stream.readInt());
+ value = stream.readInt();
}
// FIXME: not yet implementable
// void write_on(DebugInfoWriteStream* stream);
- //--------------------------------------------------------------------------------
+ //-----------------------------------------------------------------------------
// Internals only below this point
//
private void setWhere(Where where) {
- value |= (where.getValue() << WHERE_SHIFT);
+ value |= ((where.getValue() << WHERE_SHIFT) & WHERE_MASK);
}
private void setType(Type type) {
- value |= (type.getValue() << TYPE_SHIFT);
+ value |= ((type.getValue() << TYPE_SHIFT) & TYPE_MASK);
}
private void setOffset(int offset) {
- value |= (offset << OFFSET_SHIFT);
+ value |= ((offset << OFFSET_SHIFT) & OFFSET_MASK);
}
}
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/CompiledVFrame.java Thu Sep 11 11:25:43 2008 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/CompiledVFrame.java Wed Sep 17 18:02:38 2008 -0700
@@ -206,6 +206,16 @@
Assert.that( loc.isRegister(), "ints always saved to stack in 1 word" );
}
return new StackValue(valueAddr.getJLongAt(0) & 0xFFFFFFFF);
+ } else if (loc.holdsNarrowOop()) { // Holds an narrow oop?
+ if (loc.isRegister() && VM.getVM().isBigEndian()) {
+ // The callee has no clue whether the register holds an narrow oop,
+ // long or is unused. He always saves a long. Here we know
+ // a long was saved, but we only want an narrow oop back. Narrow the
+ // saved long to the narrow oop that the JVM wants.
+ return new StackValue(valueAddr.getCompOopHandleAt(VM.getVM().getIntSize()));
+ } else {
+ return new StackValue(valueAddr.getCompOopHandleAt(0));
+ }
} else if( loc.holdsOop() ) { // Holds an oop?
return new StackValue(valueAddr.getOopHandleAt(0));
} else if( loc.holdsDouble() ) {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java Thu Sep 11 11:25:43 2008 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/runtime/VM.java Wed Sep 17 18:02:38 2008 -0700
@@ -621,6 +621,11 @@
return bytes;
}
+ /** Returns true if this is a isBigEndian, false otherwise */
+ public boolean isBigEndian() {
+ return isBigEndian;
+ }
+
/** Returns true if this is a "core" build, false if either C1 or C2
is present */
public boolean isCore() {
--- a/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java Thu Sep 11 11:25:43 2008 -0700
+++ b/hotspot/agent/src/share/classes/sun/jvm/hotspot/ui/classbrowser/HTMLGenerator.java Wed Sep 17 18:02:38 2008 -0700
@@ -1135,6 +1135,8 @@
buf.append("normal");
} else if (type == Location.Type.OOP) {
buf.append("oop");
+ } else if (type == Location.Type.NARROWOOP) {
+ buf.append("narrowoop");
} else if (type == Location.Type.INT_IN_LONG) {
buf.append("int");
} else if (type == Location.Type.LNG) {
--- a/hotspot/make/jprt.properties Thu Sep 11 11:25:43 2008 -0700
+++ b/hotspot/make/jprt.properties Wed Sep 17 18:02:38 2008 -0700
@@ -295,3 +295,9 @@
${jprt.my.windows.i586.test.targets}, \
${jprt.my.windows.x64.test.targets}
+# The default test/Makefile targets that should be run
+
+# Example:
+# jprt.make.rule.test.targets=*-*-*-packtest
+#jprt.make.rule.test.targets=*-product-*-packtest
+
--- a/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Thu Sep 11 11:25:43 2008 -0700
+++ b/hotspot/src/cpu/x86/vm/c1_LIRAssembler_x86.cpp Wed Sep 17 18:02:38 2008 -0700
@@ -1129,8 +1129,8 @@
#else
__ pushl(frame_map()->address_for_slot(src ->double_stack_ix(), 0));
// push and pop the part at src + wordSize, adding wordSize for the previous push
- __ pushl(frame_map()->address_for_slot(src ->double_stack_ix(), wordSize));
- __ popl (frame_map()->address_for_slot(dest->double_stack_ix(), wordSize));
+ __ pushl(frame_map()->address_for_slot(src ->double_stack_ix(), 2 * wordSize));
+ __ popl (frame_map()->address_for_slot(dest->double_stack_ix(), 2 * wordSize));
__ popl (frame_map()->address_for_slot(dest->double_stack_ix(), 0));
#endif // _LP64
--- a/hotspot/src/share/vm/code/location.cpp Thu Sep 11 11:25:43 2008 -0700
+++ b/hotspot/src/share/vm/code/location.cpp Wed Sep 17 18:02:38 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2008 Sun Microsystems, Inc. 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
@@ -26,7 +26,7 @@
#include "incls/_location.cpp.incl"
void Location::print_on(outputStream* st) const {
- if(type() == invalid && !legal_offset_in_bytes(offset() * BytesPerInt)) {
+ if(type() == invalid) {
// product of Location::invalid_loc() or Location::Location().
switch (where()) {
case on_stack: st->print("empty"); break;
@@ -42,6 +42,7 @@
switch (type()) {
case normal: break;
case oop: st->print(",oop"); break;
+ case narrowoop: st->print(",narrowoop"); break;
case int_in_long: st->print(",int"); break;
case lng: st->print(",long"); break;
case float_in_dbl: st->print(",float"); break;
@@ -53,17 +54,17 @@
Location::Location(DebugInfoReadStream* stream) {
- _value = (uint16_t) stream->read_int();
+ _value = (juint) stream->read_int();
}
void Location::write_on(DebugInfoWriteStream* stream) {
- stream->write_int(_value & 0x0000FFFF);
+ stream->write_int(_value);
}
// Valid argument to Location::new_stk_loc()?
bool Location::legal_offset_in_bytes(int offset_in_bytes) {
if ((offset_in_bytes % BytesPerInt) != 0) return false;
- return (offset_in_bytes / BytesPerInt) < (OFFSET_MASK >> OFFSET_SHIFT);
+ return (juint)(offset_in_bytes / BytesPerInt) < (OFFSET_MASK >> OFFSET_SHIFT);
}
--- a/hotspot/src/share/vm/code/location.hpp Thu Sep 11 11:25:43 2008 -0700
+++ b/hotspot/src/share/vm/code/location.hpp Wed Sep 17 18:02:38 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2008 Sun Microsystems, Inc. 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
@@ -28,10 +28,10 @@
//
// Encoding:
//
-// bits:
-// Where: [15]
-// Type: [14..12]
-// Offset: [11..0]
+// bits (use low bits for best compression):
+// Type: [3..0]
+// Where: [4]
+// Offset: [31..5]
class Location VALUE_OBJ_CLASS_SPEC {
friend class VMStructs;
@@ -42,6 +42,7 @@
};
enum Type {
+ invalid, // Invalid location
normal, // Ints, floats, double halves
oop, // Oop (please GC me!)
int_in_long, // Integer held in long register
@@ -49,21 +50,21 @@
float_in_dbl, // Float held in double register
dbl, // Double held in one register
addr, // JSR return address
- invalid // Invalid location
+ narrowoop // Narrow Oop (please GC me!)
};
private:
enum {
- OFFSET_MASK = (jchar) 0x0FFF,
- OFFSET_SHIFT = 0,
- TYPE_MASK = (jchar) 0x7000,
- TYPE_SHIFT = 12,
- WHERE_MASK = (jchar) 0x8000,
- WHERE_SHIFT = 15
+ TYPE_MASK = (juint) 0x0F,
+ TYPE_SHIFT = 0,
+ WHERE_MASK = (juint) 0x10,
+ WHERE_SHIFT = 4,
+ OFFSET_MASK = (juint) 0xFFFFFFE0,
+ OFFSET_SHIFT = 5
};
- uint16_t _value;
+ juint _value;
// Create a bit-packed Location
Location(Where where_, Type type_, unsigned offset_) {
@@ -74,9 +75,9 @@
}
inline void set(Where where_, Type type_, unsigned offset_) {
- _value = (uint16_t) ((where_ << WHERE_SHIFT) |
- (type_ << TYPE_SHIFT) |
- ((offset_ << OFFSET_SHIFT) & OFFSET_MASK));
+ _value = (juint) ((where_ << WHERE_SHIFT) |
+ (type_ << TYPE_SHIFT) |
+ ((offset_ << OFFSET_SHIFT) & OFFSET_MASK));
}
public:
@@ -86,7 +87,7 @@
// Register location Factory
static Location new_reg_loc( Type t, VMReg reg ) { return Location(in_register, t, reg->value()); }
// Default constructor
- Location() { set(on_stack,invalid,(unsigned) -1); }
+ Location() { set(on_stack,invalid,0); }
// Bit field accessors
Where where() const { return (Where) ((_value & WHERE_MASK) >> WHERE_SHIFT);}
--- a/hotspot/src/share/vm/opto/addnode.cpp Thu Sep 11 11:25:43 2008 -0700
+++ b/hotspot/src/share/vm/opto/addnode.cpp Wed Sep 17 18:02:38 2008 -0700
@@ -157,6 +157,7 @@
Node *a12 = add1->in(2);
const Type *t12 = phase->type( a12 );
if( t12->singleton() && t12 != Type::TOP && (add1 != add1->in(1)) ) {
+ assert(add1->in(1) != this, "dead loop in AddNode::Ideal");
add2 = add1->clone();
add2->set_req(2, in(2));
add2 = phase->transform(add2);
@@ -173,6 +174,7 @@
Node *a22 = add2->in(2);
const Type *t22 = phase->type( a22 );
if( t22->singleton() && t22 != Type::TOP && (add2 != add2->in(1)) ) {
+ assert(add2->in(1) != this, "dead loop in AddNode::Ideal");
Node *addx = add2->clone();
addx->set_req(1, in(1));
addx->set_req(2, add2->in(1));
--- a/hotspot/src/share/vm/opto/callnode.cpp Thu Sep 11 11:25:43 2008 -0700
+++ b/hotspot/src/share/vm/opto/callnode.cpp Wed Sep 17 18:02:38 2008 -0700
@@ -334,6 +334,9 @@
case Type::InstPtr:
st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,t->isa_oopptr()->const_oop());
break;
+ case Type::NarrowOop:
+ st->print(" %s%d]=#Ptr" INTPTR_FORMAT,msg,i,t->make_ptr()->isa_oopptr()->const_oop());
+ break;
case Type::RawPtr:
st->print(" %s%d]=#Raw" INTPTR_FORMAT,msg,i,t->is_rawptr());
break;
--- a/hotspot/src/share/vm/opto/compile.cpp Thu Sep 11 11:25:43 2008 -0700
+++ b/hotspot/src/share/vm/opto/compile.cpp Wed Sep 17 18:02:38 2008 -0700
@@ -1967,6 +1967,7 @@
!n->is_Proj() &&
nop != Op_CreateEx &&
nop != Op_CheckCastPP &&
+ nop != Op_DecodeN &&
!n->is_Mem() ) {
Node *x = n->clone();
call->set_req( TypeFunc::Parms, x );
@@ -2075,20 +2076,27 @@
case Op_CmpP:
// Do this transformation here to preserve CmpPNode::sub() and
// other TypePtr related Ideal optimizations (for example, ptr nullness).
- if( n->in(1)->is_DecodeN() ) {
+ if (n->in(1)->is_DecodeN() || n->in(2)->is_DecodeN()) {
+ Node* in1 = n->in(1);
+ Node* in2 = n->in(2);
+ if (!in1->is_DecodeN()) {
+ in2 = in1;
+ in1 = n->in(2);
+ }
+ assert(in1->is_DecodeN(), "sanity");
+
Compile* C = Compile::current();
- Node* in2 = NULL;
- if( n->in(2)->is_DecodeN() ) {
- in2 = n->in(2)->in(1);
- } else if ( n->in(2)->Opcode() == Op_ConP ) {
- const Type* t = n->in(2)->bottom_type();
- if (t == TypePtr::NULL_PTR) {
- Node *in1 = n->in(1);
+ Node* new_in2 = NULL;
+ if (in2->is_DecodeN()) {
+ new_in2 = in2->in(1);
+ } else if (in2->Opcode() == Op_ConP) {
+ const Type* t = in2->bottom_type();
+ if (t == TypePtr::NULL_PTR && UseImplicitNullCheckForNarrowOop) {
if (Matcher::clone_shift_expressions) {
// x86, ARM and friends can handle 2 adds in addressing mode.
// Decode a narrow oop and do implicit NULL check in address
// [R12 + narrow_oop_reg<<3 + offset]
- in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR);
+ new_in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR);
} else {
// Don't replace CmpP(o ,null) if 'o' is used in AddP
// to generate implicit NULL check on Sparc where
@@ -2099,16 +2107,22 @@
break;
}
if (i >= in1->outcnt()) {
- in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR);
+ new_in2 = ConNode::make(C, TypeNarrowOop::NULL_PTR);
}
}
} else if (t->isa_oopptr()) {
- in2 = ConNode::make(C, t->make_narrowoop());
+ new_in2 = ConNode::make(C, t->make_narrowoop());
}
}
- if( in2 != NULL ) {
- Node* cmpN = new (C, 3) CmpNNode(n->in(1)->in(1), in2);
+ if (new_in2 != NULL) {
+ Node* cmpN = new (C, 3) CmpNNode(in1->in(1), new_in2);
n->subsume_by( cmpN );
+ if (in1->outcnt() == 0) {
+ in1->disconnect_inputs(NULL);
+ }
+ if (in2->outcnt() == 0) {
+ in2->disconnect_inputs(NULL);
+ }
}
}
break;
@@ -2214,6 +2228,9 @@
// Replacing Opaque nodes with their input in final_graph_reshaping_impl(),
// requires that the walk visits a node's inputs before visiting the node.
static void final_graph_reshaping_walk( Node_Stack &nstack, Node *root, Final_Reshape_Counts &fpu ) {
+ ResourceArea *area = Thread::current()->resource_area();
+ Unique_Node_List sfpt(area);
+
fpu._visited.set(root->_idx); // first, mark node as visited
uint cnt = root->req();
Node *n = root;
@@ -2224,6 +2241,8 @@
Node* m = n->in(i);
++i;
if (m != NULL && !fpu._visited.test_set(m->_idx)) {
+ if (m->is_SafePoint() && m->as_SafePoint()->jvms() != NULL)
+ sfpt.push(m);
cnt = m->req();
nstack.push(n, i); // put on stack parent and next input's index
n = m;
@@ -2240,6 +2259,41 @@
nstack.pop(); // Shift to the next node on stack
}
}
+
+ // Go over safepoints nodes to skip DecodeN nodes for debug edges.
+ // It could be done for an uncommon traps or any safepoints/calls
+ // if the DecodeN node is referenced only in a debug info.
+ while (sfpt.size() > 0) {
+ n = sfpt.pop();
+ JVMState *jvms = n->as_SafePoint()->jvms();
+ assert(jvms != NULL, "sanity");
+ int start = jvms->debug_start();
+ int end = n->req();
+ bool is_uncommon = (n->is_CallStaticJava() &&
+ n->as_CallStaticJava()->uncommon_trap_request() != 0);
+ for (int j = start; j < end; j++) {
+ Node* in = n->in(j);
+ if (in->is_DecodeN()) {
+ bool safe_to_skip = true;
+ if (!is_uncommon ) {
+ // Is it safe to skip?
+ for (uint i = 0; i < in->outcnt(); i++) {
+ Node* u = in->raw_out(i);
+ if (!u->is_SafePoint() ||
+ u->is_Call() && u->as_Call()->has_non_debug_use(n)) {
+ safe_to_skip = false;
+ }
+ }
+ }
+ if (safe_to_skip) {
+ n->set_req(j, in->in(1));
+ }
+ if (in->outcnt() == 0) {
+ in->disconnect_inputs(NULL);
+ }
+ }
+ }
+ }
}
//------------------------------final_graph_reshaping--------------------------
--- a/hotspot/src/share/vm/opto/graphKit.cpp Thu Sep 11 11:25:43 2008 -0700
+++ b/hotspot/src/share/vm/opto/graphKit.cpp Wed Sep 17 18:02:38 2008 -0700
@@ -1212,6 +1212,7 @@
Deoptimization::Action_make_not_entrant,
NULL, "assert_null");
} else {
+ replace_in_map(value, zerocon(type));
builtin_throw(reason);
}
}
@@ -1960,6 +1961,7 @@
// method will be compiled to handle NULLs.
PreserveJVMState pjvms(this);
set_control(*null_control);
+ replace_in_map(value, null());
uncommon_trap(Deoptimization::Reason_null_check,
Deoptimization::Action_make_not_entrant);
(*null_control) = top(); // NULL path is dead
--- a/hotspot/src/share/vm/opto/lcm.cpp Thu Sep 11 11:25:43 2008 -0700
+++ b/hotspot/src/share/vm/opto/lcm.cpp Wed Sep 17 18:02:38 2008 -0700
@@ -58,6 +58,9 @@
not_null_block = _succs[0];
null_block = _succs[1];
}
+ while (null_block->is_Empty() == Block::empty_with_goto) {
+ null_block = null_block->_succs[0];
+ }
// Search the exception block for an uncommon trap.
// (See Parse::do_if and Parse::do_ifnull for the reason
@@ -149,6 +152,10 @@
const TypePtr *adr_type = NULL; // Do not need this return value here
const Node* base = mach->get_base_and_disp(offset, adr_type);
if (base == NULL || base == NodeSentinel) {
+ // Narrow oop address doesn't have base, only index
+ if( val->bottom_type()->isa_narrowoop() &&
+ MacroAssembler::needs_explicit_null_check(offset) )
+ continue; // Give up if offset is beyond page size
// cannot reason about it; is probably not implicit null exception
} else {
const TypePtr* tptr = base->bottom_type()->is_ptr();
--- a/hotspot/src/share/vm/opto/loopopts.cpp Thu Sep 11 11:25:43 2008 -0700
+++ b/hotspot/src/share/vm/opto/loopopts.cpp Wed Sep 17 18:02:38 2008 -0700
@@ -932,7 +932,7 @@
// to fold a StoreP and an AddP together (as part of an
// address expression) and the AddP and StoreP have
// different controls.
- if( !x->is_Load() ) _igvn._worklist.yank(x);
+ if( !x->is_Load() && !x->is_DecodeN() ) _igvn._worklist.yank(x);
}
_igvn.remove_dead_node(n);
}
--- a/hotspot/src/share/vm/opto/output.cpp Thu Sep 11 11:25:43 2008 -0700
+++ b/hotspot/src/share/vm/opto/output.cpp Wed Sep 17 18:02:38 2008 -0700
@@ -685,6 +685,8 @@
} else if( t->base() == Type::Int && OptoReg::is_reg(regnum) ) {
array->append(new_loc_value( _regalloc, regnum, Matcher::int_in_long
? Location::int_in_long : Location::normal ));
+ } else if( t->base() == Type::NarrowOop ) {
+ array->append(new_loc_value( _regalloc, regnum, Location::narrowoop ));
} else {
array->append(new_loc_value( _regalloc, regnum, _regalloc->is_oop(local) ? Location::oop : Location::normal ));
}
@@ -704,6 +706,13 @@
case Type::KlassPtr: // fall through
array->append(new ConstantOopWriteValue(t->isa_oopptr()->const_oop()->encoding()));
break;
+ case Type::NarrowOop:
+ if (t == TypeNarrowOop::NULL_PTR) {
+ array->append(new ConstantOopWriteValue(NULL));
+ } else {
+ array->append(new ConstantOopWriteValue(t->make_ptr()->isa_oopptr()->const_oop()->encoding()));
+ }
+ break;
case Type::Int:
array->append(new ConstantIntValue(t->is_int()->get_con()));
break;
@@ -878,9 +887,14 @@
}
} else if( !obj_node->is_Con() ) {
OptoReg::Name obj_reg = _regalloc->get_reg_first(obj_node);
- scval = new_loc_value( _regalloc, obj_reg, Location::oop );
+ if( obj_node->bottom_type()->base() == Type::NarrowOop ) {
+ scval = new_loc_value( _regalloc, obj_reg, Location::narrowoop );
+ } else {
+ scval = new_loc_value( _regalloc, obj_reg, Location::oop );
+ }
} else {
- scval = new ConstantOopWriteValue(obj_node->bottom_type()->is_instptr()->const_oop()->encoding());
+ const TypePtr *tp = obj_node->bottom_type()->make_ptr();
+ scval = new ConstantOopWriteValue(tp->is_instptr()->const_oop()->encoding());
}
OptoReg::Name box_reg = BoxLockNode::stack_slot(box_node);
--- a/hotspot/src/share/vm/opto/reg_split.cpp Thu Sep 11 11:25:43 2008 -0700
+++ b/hotspot/src/share/vm/opto/reg_split.cpp Wed Sep 17 18:02:38 2008 -0700
@@ -527,6 +527,7 @@
// Initialize needs_phi and needs_split
bool needs_phi = false;
bool needs_split = false;
+ bool has_phi = false;
// Walk the predecessor blocks to check inputs for that live range
// Grab predecessor block header
n1 = b->pred(1);
@@ -570,28 +571,30 @@
}
} // End for all potential Phi inputs
- // If a phi is needed, check for it
- if( needs_phi ) {
- // check block for appropriate phinode & update edges
- for( insidx = 1; insidx <= b->end_idx(); insidx++ ) {
- n1 = b->_nodes[insidx];
- // bail if this is not a phi
- phi = n1->is_Phi() ? n1->as_Phi() : NULL;
- if( phi == NULL ) {
- // Keep track of index of first non-PhiNode instruction in block
- non_phi = insidx;
- // break out of the for loop as we have handled all phi nodes
- break;
- }
- // must be looking at a phi
- if( Find_id(n1) == lidxs.at(slidx) ) {
- // found the necessary phi
- needs_phi = false;
- // initialize the Reaches entry for this LRG
- Reachblock[slidx] = phi;
- break;
- } // end if found correct phi
- } // end for all phi's
+ // check block for appropriate phinode & update edges
+ for( insidx = 1; insidx <= b->end_idx(); insidx++ ) {
+ n1 = b->_nodes[insidx];
+ // bail if this is not a phi
+ phi = n1->is_Phi() ? n1->as_Phi() : NULL;
+ if( phi == NULL ) {
+ // Keep track of index of first non-PhiNode instruction in block
+ non_phi = insidx;
+ // break out of the for loop as we have handled all phi nodes
+ break;
+ }
+ // must be looking at a phi
+ if( Find_id(n1) == lidxs.at(slidx) ) {
+ // found the necessary phi
+ needs_phi = false;
+ has_phi = true;
+ // initialize the Reaches entry for this LRG
+ Reachblock[slidx] = phi;
+ break;
+ } // end if found correct phi
+ } // end for all phi's
+
+ // If a phi is needed or exist, check for it
+ if( needs_phi || has_phi ) {
// add new phinode if one not already found
if( needs_phi ) {
// create a new phi node and insert it into the block
@@ -695,7 +698,8 @@
}
}
assert( u, "at least 1 valid input expected" );
- if( i >= cnt ) { // Didn't find 2+ unique inputs?
+ if( i >= cnt ) { // Found one unique input
+ assert(Find_id(n) == Find_id(u), "should be the same lrg");
n->replace_by(u); // Then replace with unique input
n->disconnect_inputs(NULL);
b->_nodes.remove(insidx);
--- a/hotspot/src/share/vm/runtime/arguments.cpp Thu Sep 11 11:25:43 2008 -0700
+++ b/hotspot/src/share/vm/runtime/arguments.cpp Wed Sep 17 18:02:38 2008 -0700
@@ -1204,15 +1204,17 @@
// Turn off until bug is fixed.
// FLAG_SET_ERGO(bool, UseCompressedOops, true);
}
+#ifdef _WIN64
+ if (UseLargePages && UseCompressedOops) {
+ // Cannot allocate guard pages for implicit checks in indexed addressing
+ // mode, when large pages are specified on windows.
+ FLAG_SET_DEFAULT(UseImplicitNullCheckForNarrowOop, false);
+ }
+#endif // _WIN64
} else {
if (UseCompressedOops && !FLAG_IS_DEFAULT(UseCompressedOops)) {
// If specified, give a warning
- if (UseConcMarkSweepGC){
- warning("Compressed Oops does not work with CMS");
- } else {
- warning(
- "Max heap size too large for Compressed Oops");
- }
+ warning( "Max heap size too large for Compressed Oops");
FLAG_SET_DEFAULT(UseCompressedOops, false);
}
}
--- a/hotspot/src/share/vm/runtime/globals.hpp Thu Sep 11 11:25:43 2008 -0700
+++ b/hotspot/src/share/vm/runtime/globals.hpp Wed Sep 17 18:02:38 2008 -0700
@@ -294,6 +294,9 @@
lp64_product(bool, CheckCompressedOops, trueInDebug, \
"generate checks in encoding/decoding code") \
\
+ product(bool, UseImplicitNullCheckForNarrowOop, true, \
+ "generate implicit null check in indexed addressing mode.") \
+ \
/* UseMembar is theoretically a temp flag used for memory barrier \
* removal testing. It was supposed to be removed before FCS but has \
* been re-added (see 6401008) */ \
--- a/hotspot/src/share/vm/runtime/stackValue.cpp Thu Sep 11 11:25:43 2008 -0700
+++ b/hotspot/src/share/vm/runtime/stackValue.cpp Wed Sep 17 18:02:38 2008 -0700
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2006 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2008 Sun Microsystems, Inc. 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
@@ -86,6 +86,22 @@
case Location::lng:
// Long value in an aligned adjacent pair
return new StackValue(*(intptr_t*)value_addr);
+ case Location::narrowoop: {
+ union { intptr_t p; narrowOop noop;} value;
+ value.p = (intptr_t) CONST64(0xDEADDEAFDEADDEAF);
+ if (loc.is_register()) {
+ // The callee has no clue whether the register holds an int,
+ // long or is unused. He always saves a long. Here we know
+ // a long was saved, but we only want an int back. Narrow the
+ // saved long to the int that the JVM wants.
+ value.noop = (narrowOop) *(julong*) value_addr;
+ } else {
+ value.noop = *(narrowOop*) value_addr;
+ }
+ // Decode narrowoop and wrap a handle around the oop
+ Handle h(oopDesc::decode_heap_oop(value.noop));
+ return new StackValue(h);
+ }
#endif
case Location::oop: {
Handle h(*(oop *)value_addr); // Wrap a handle around the oop
--- a/hotspot/src/share/vm/runtime/thread.cpp Thu Sep 11 11:25:43 2008 -0700
+++ b/hotspot/src/share/vm/runtime/thread.cpp Wed Sep 17 18:02:38 2008 -0700
@@ -2756,13 +2756,17 @@
// For now, just manually iterate through them.
tc->do_thread(VMThread::vm_thread());
Universe::heap()->gc_threads_do(tc);
- {
- // Grab the Terminator_lock to prevent watcher_thread from being terminated.
- MutexLockerEx mu(Terminator_lock, Mutex::_no_safepoint_check_flag);
- WatcherThread *wt = WatcherThread::watcher_thread();
- if (wt != NULL)
- tc->do_thread(wt);
- }
+ WatcherThread *wt = WatcherThread::watcher_thread();
+ // Strictly speaking, the following NULL check isn't sufficient to make sure
+ // the data for WatcherThread is still valid upon being examined. However,
+ // considering that WatchThread terminates when the VM is on the way to
+ // exit at safepoint, the chance of the above is extremely small. The right
+ // way to prevent termination of WatcherThread would be to acquire
+ // Terminator_lock, but we can't do that without violating the lock rank
+ // checking in some cases.
+ if (wt != NULL)
+ tc->do_thread(wt);
+
// If CompilerThreads ever become non-JavaThreads, add them here
}
--- a/hotspot/src/share/vm/runtime/virtualspace.cpp Thu Sep 11 11:25:43 2008 -0700
+++ b/hotspot/src/share/vm/runtime/virtualspace.cpp Wed Sep 17 18:02:38 2008 -0700
@@ -380,7 +380,8 @@
bool large, char* requested_address) :
ReservedSpace(size, alignment, large,
requested_address,
- UseCompressedOops ? lcm(os::vm_page_size(), alignment) : 0) {
+ UseCompressedOops && UseImplicitNullCheckForNarrowOop ?
+ lcm(os::vm_page_size(), alignment) : 0) {
// Only reserved space for the java heap should have a noaccess_prefix
// if using compressed oops.
protect_noaccess_prefix(size);
@@ -391,7 +392,8 @@
const size_t suffix_size,
const size_t suffix_align) :
ReservedSpace(prefix_size, prefix_align, suffix_size, suffix_align,
- UseCompressedOops ? lcm(os::vm_page_size(), prefix_align) : 0) {
+ UseCompressedOops && UseImplicitNullCheckForNarrowOop ?
+ lcm(os::vm_page_size(), prefix_align) : 0) {
protect_noaccess_prefix(prefix_size+suffix_size);
}
--- a/hotspot/src/share/vm/runtime/vmStructs.cpp Thu Sep 11 11:25:43 2008 -0700
+++ b/hotspot/src/share/vm/runtime/vmStructs.cpp Wed Sep 17 18:02:38 2008 -0700
@@ -1577,6 +1577,7 @@
\
declare_constant(Location::normal) \
declare_constant(Location::oop) \
+ declare_constant(Location::narrowoop) \
declare_constant(Location::int_in_long) \
declare_constant(Location::lng) \
declare_constant(Location::float_in_dbl) \
--- a/hotspot/test/Makefile Thu Sep 11 11:25:43 2008 -0700
+++ b/hotspot/test/Makefile Wed Sep 17 18:02:38 2008 -0700
@@ -1,5 +1,5 @@
#
-# Copyright 2006 Sun Microsystems, Inc. All Rights Reserved.
+# Copyright 1995-2008 Sun Microsystems, Inc. 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
@@ -19,17 +19,18 @@
# Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
# CA 95054 USA or visit www.sun.com if you need additional information or
# have any questions.
-#
+#
#
#
-# Makefile to run jtreg
+# Makefile to run various jdk tests
#
+# Get OS/ARCH specifics
OSNAME = $(shell uname -s)
+SLASH_JAVA = /java
ifeq ($(OSNAME), SunOS)
PLATFORM = solaris
- JCT_PLATFORM = solaris
ARCH = $(shell uname -p)
ifeq ($(ARCH), i386)
ARCH=i586
@@ -37,203 +38,165 @@
endif
ifeq ($(OSNAME), Linux)
PLATFORM = linux
- JCT_PLATFORM = linux
ARCH = $(shell uname -m)
ifeq ($(ARCH), i386)
- ARCH=i586
+ ARCH = i586
endif
endif
ifeq ($(OSNAME), Windows_NT)
PLATFORM = windows
- JCT_PLATFORM = win32
+ SLASH_JAVA = J:
ifeq ($(word 1, $(PROCESSOR_IDENTIFIER)),ia64)
- ARCH=ia64
+ ARCH = ia64
else
ifeq ($(word 1, $(PROCESSOR_IDENTIFIER)),AMD64)
- ARCH=x64
+ ARCH = x64
else
ifeq ($(word 1, $(PROCESSOR_IDENTIFIER)),EM64T)
- ARCH=x64
+ ARCH = x64
else
- ARCH=i586
+ ARCH = i586
endif
endif
endif
-endif
-
-# Default bundle of all test results (passed or not)
-JPRT_ARCHIVE_BUNDLE=$(TEST_ROOT)/JPRT_ARCHIVE_BUNDLE.zip
-
-# Default home for JTREG
-ifeq ($(PLATFORM), windows)
- JT_HOME = J:/svc/jct-tools3.2.2_01
-else
- JT_HOME = /java/svc/jct-tools3.2.2_01
+ EXESUFFIX = .exe
endif
-# Default JTREG to run
-JTREG = $(JT_HOME)/$(JCT_PLATFORM)/bin/jtreg
-
-# Root of this test area
-TEST_ROOT := $(shell pwd)
-
-# Default JDK to test
-JAVA_HOME = $(TEST_ROOT)/../build/$(PLATFORM)-$(ARCH)
+# Utilities used
+CD = cd
+CP = cp
+ECHO = echo
+MKDIR = mkdir
+ZIP = zip
-# The test directories to run
-DEFAULT_TESTDIRS = serviceability
-TESTDIRS = $(DEFAULT_TESTDIRS)
-
-# Files that hold total passed and failed counts (passed==0 is bad)
-JTREG_TOTALS_DIR = $(TEST_ROOT)/JTREG_TOTALS_$(PLATFORM)_$(ARCH)
-JTREG_FAILED = $(JTREG_TOTALS_DIR)/failed_count
-JTREG_PASSED = $(JTREG_TOTALS_DIR)/passed_count
+# Root of this test area (important to use full paths in some places)
+TEST_ROOT := $(shell pwd)
# Root of all test results
-JTREG_ALL_OUTPUT_DIRNAME = JTREG_OUTPUT_$(PLATFORM)_$(ARCH)
-JTREG_ALL_OUTPUT_DIR = $(TEST_ROOT)/$(JTREG_ALL_OUTPUT_DIRNAME)
-
-# Test results for one test directory
-JTREG_TEST_OUTPUT_DIR = $(JTREG_ALL_OUTPUT_DIR)/$@
-JTREG_TEST_REPORT_DIR = $(JTREG_TEST_OUTPUT_DIR)/JTreport
-JTREG_TEST_WORK_DIR = $(JTREG_TEST_OUTPUT_DIR)/JTwork
-JTREG_TEST_SUMMARY = $(JTREG_TEST_REPORT_DIR)/summary.txt
-
-# Temp files used by this Makefile
-JTREG_TEST_TEMP_DIR = $(JTREG_ALL_OUTPUT_DIR)/$@/temp
-JTREG_TEMP_PASSED = $(JTREG_TEST_TEMP_DIR)/passed
-JTREG_TEMP_FAILED = $(JTREG_TEST_TEMP_DIR)/failed
-JTREG_TEMP_OUTPUT = $(JTREG_TEST_TEMP_DIR)/output
-JTREG_TEMP_RESULTS = $(JTREG_TEST_TEMP_DIR)/results
-
-# JTREG options (different for 2.1.6 and 3.2.2_01)
-JTREG_COMMON_OPTIONS = -r:$(JTREG_TEST_REPORT_DIR) \
- -w:$(JTREG_TEST_WORK_DIR) \
- -testjdk:$(JAVA_HOME) \
- -automatic \
- -verbose:all
-JTREG_216_OPTIONS = $(JTREG_COMMON_OPTIONS) $@ $(JAVA_ARGS)
-JTREG_322_OPTIONS = $(JTREG_COMMON_OPTIONS) $(JAVA_ARGS:%=-vmoption:%) $@
-
-# Default make rule
-all: clean check tests
-
-# Chaeck to make sure these directories exist
-check: $(JT_HOME) $(JAVA_HOME) $(JTREG)
+ABS_BUILD_ROOT = $(TEST_ROOT)/../build/$(PLATFORM)-$(ARCH)
+ABS_TEST_OUTPUT_DIR = $(ABS_BUILD_ROOT)/testoutput
-# Prime the test run
-primecounts: FRC
- @rm -f -r $(JTREG_TOTALS_DIR)
- @mkdir -p $(JTREG_TOTALS_DIR)
- @echo "0" > $(JTREG_FAILED)
- @echo "0" > $(JTREG_PASSED)
+# Expect JPRT to set PRODUCT_HOME (the product or jdk in this case to test)
+ifndef PRODUCT_HOME
+ # Try to use j2sdk-image if it exists
+ ABS_JDK_IMAGE = $(ABS_BUILD_ROOT)/j2sdk-image
+ PRODUCT_HOME := \
+ $(shell \
+ if [ -d $(ABS_JDK_IMAGE) ] ; then \
+ $(ECHO) "$(ABS_JDK_IMAGE)"; \
+ else \
+ $(ECHO) "$(ABS_BUILD_ROOT)" ; \
+ fi)
+endif
-# Run the tests and determine the 'make' command exit status
-# Ultimately we determine the make exit code based on the passed/failed count
-tests: primecounts $(TESTDIRS)
- @echo "JTREG TOTAL: passed=`cat $(JTREG_PASSED)` failed=`cat $(JTREG_FAILED)`"
- zip -q -r $(JPRT_ARCHIVE_BUNDLE) $(JTREG_ALL_OUTPUT_DIRNAME)
- @if [ `cat $(JTREG_FAILED)` -ne 0 -o \
- `cat $(JTREG_PASSED)` -le 0 ] ; then \
- echo "JTREG FAILED"; \
- exit 1; \
- else \
- echo "JTREG PASSED"; \
- exit 0; \
- fi
-
-# Just make sure these directires exist
-$(JT_HOME) $(JAVA_HOME): FRC
- @if [ ! -d $@ ] ; then \
- echo "ERROR: Directory $@ does not exist"; \
- exit 1; \
- fi
-
-# Make sure this file exists
-$(JTREG): FRC
- @if [ ! -f $@ ] ; then \
- echo "ERROR: File $@ does not exist"; \
- exit 1; \
- fi
+# Expect JPRT to set JAVA_ARGS (e.g. -server etc.)
+JAVA_OPTIONS =
+ifdef JAVA_ARGS
+ JAVA_OPTIONS = $(JAVA_ARGS)
+endif
-# Process each test directory one by one, this rule always completes.
-# Note that the use of 'tee' tosses the jtreg process exit status, this
-# is as expected because even if jtreg fails, we need to save the
-# output. So we update the JTREG_PASSED and JTREG_FAILED count files.
-# Note that missing the 'results:' line in the last few lines of output
-# will indicate a failure (or a bump by one of the JTREG_FAILED file.
-# Note that passed: 0 or no passed: indication means a failure.
-# Note that any indication of the word 'failed' indicates failure.
-# Ultimately if the contents of JTREG_FAILED is not 0, we have failed
-# tests, and if the contents of JTREG_PASSED is 0, we consider that a
-# failure.
-$(TESTDIRS): FRC
- @if [ ! -d $@ ] ; then \
- echo "ERROR: Directory $@ does not exist"; \
- exit 1; \
- fi
- @echo "---------------------------------------------------"
- @rm -f -r $(JTREG_TEST_OUTPUT_DIR)
- @mkdir -p $(JTREG_TEST_OUTPUT_DIR)
- @mkdir -p $(JTREG_TEST_WORK_DIR)
- @mkdir -p $(JTREG_TEST_WORK_DIR)/scratch
- @mkdir -p $(JTREG_TEST_REPORT_DIR)
- @mkdir -p $(JTREG_TEST_TEMP_DIR)
- @echo "Testing $@"
- @echo "Using JAVA_HOME=$(JAVA_HOME)"
- @echo "Using JAVA_ARGS=$(JAVA_ARGS)"
- @if [ "`$(JTREG) -help 2>&1 | fgrep -- -vmoption`" != "" ] ; then \
- echo "Assume we are using jtreg 3.2.2_01 or newer"; \
- echo "$(JTREG) $(JTREG_322_OPTIONS)"; \
- $(JTREG) $(JTREG_322_OPTIONS) 2>&1 | tee $(JTREG_TEMP_OUTPUT) ; \
- else \
- echo "Assume we are using jtreg 2.1.6"; \
- echo "$(JTREG) $(JTREG_216_OPTIONS)"; \
- $(JTREG) $(JTREG_216_OPTIONS) 2>&1 | tee $(JTREG_TEMP_OUTPUT) ; \
- fi
- @echo "---------------------------------------------------"
- @echo "Extracting passed and failed counts from jtreg output"
- @tail -10 $(JTREG_TEMP_OUTPUT) | fgrep -i 'results:' | \
- tail -1 | tee $(JTREG_TEMP_RESULTS)
- @sed -e 's@.*\ passed:\ \([1-9][0-9]*\).*@\1@' $(JTREG_TEMP_RESULTS) \
- > $(JTREG_TEMP_PASSED)
- @if [ "`cat $(JTREG_TEMP_PASSED)`" = "" ] ; then \
- echo "ERROR: No passed indication in results"; \
- expr `cat $(JTREG_FAILED)` '+' 1 > $(JTREG_FAILED); \
- elif [ `cat $(JTREG_TEMP_PASSED)` -le 0 ] ; then \
- echo "ERROR: Passed count appears to be 0"; \
- expr `cat $(JTREG_FAILED)` '+' 1 > $(JTREG_FAILED); \
- elif [ "`fgrep -i failed $(JTREG_TEMP_RESULTS)`" = "" ] ; then \
- echo "No indication anything failed"; \
- expr `cat $(JTREG_PASSED)` '+' `cat $(JTREG_TEMP_PASSED)` \
- > $(JTREG_PASSED); \
- else \
- sed -e 's@.*\ failed:\ \([1-9][0-9]*\).*@\1@' $(JTREG_TEMP_FAILED) \
- > $(JTREG_TEMP_FAILED); \
- if [ "`cat $(JTREG_TEMP_FAILED)`" = "" ] ; then \
- echo "ERROR: Failed pattern but no failed count in results"; \
- expr `cat $(JTREG_FAILED)` '+' 1 > $(JTREG_FAILED); \
- elif [ `cat $(JTREG_TEMP_FAILED)` -le 0 ] ; then \
- echo "ERROR: Failed count is 0, did something failed or not?"; \
- expr `cat $(JTREG_FAILED)` '+' 1 > $(JTREG_FAILED); \
- else \
- expr `cat $(JTREG_FAILED)` '+' `cat $(JTREG_TEMP_FAILED)` \
- > $(JTREG_FAILED); \
- fi; \
- fi
- @echo "---------------------------------------------------"
- @echo "Summary: "
- @if [ -f $(JTREG_TEST_SUMMARY) ] ; then \
- cat $(JTREG_TEST_SUMMARY) ; \
- else \
- echo "ERROR: Missing $(JTREG_TEST_SUMMARY)"; \
- fi
- @echo "---------------------------------------------------"
+# Expect JPRT to set JPRT_ARCHIVE_BUNDLE (path to zip bundle for results)
+ARCHIVE_BUNDLE = $(ABS_TEST_OUTPUT_DIR)/ARCHIVE_BUNDLE.zip
+ifdef JPRT_ARCHIVE_BUNDLE
+ ARCHIVE_BUNDLE = $(JPRT_ARCHIVE_BUNDLE)
+endif
+
+# How to create the test bundle (pass or fail, we want to create this)
+BUNDLE_UP = ( $(MKDIR) -p `dirname $(ARCHIVE_BUNDLE)` \
+ && $(CD) $(ABS_TEST_OUTPUT_DIR) \
+ && $(ZIP) -q -r $(ARCHIVE_BUNDLE) . )
+BUNDLE_UP_FAILED = ( exitCode=$$? && $(BUNDLE_UP) && exit $${exitCode} )
+
+################################################################
+
+# Default make rule (runs jtreg_tests)
+all: jtreg_tests
+ @$(ECHO) "Testing completed successfully"
+
+# Prep for output
+prep: clean
+ @$(MKDIR) -p $(ABS_TEST_OUTPUT_DIR)
+ @$(MKDIR) -p `dirname $(ARCHIVE_BUNDLE)`
# Cleanup
clean:
- rm -f -r $(JTREG_ALL_OUTPUT_DIR)
- rm -f $(JPRT_ARCHIVE_BUNDLE)
+ $(RM) -r $(ABS_TEST_OUTPUT_DIR)
+ $(RM) $(ARCHIVE_BUNDLE)
+
+################################################################
+
+# jtreg tests
+
+# Expect JT_HOME to be set for jtreg tests. (home for jtreg)
+JT_HOME = $(SLASH_JAVA)/re/jtreg/4.0/promoted/latest/binaries/jtreg
+ifdef JPRT_JTREG_HOME
+ JT_HOME = $(JPRT_JTREG_HOME)
+endif
+
+# Expect JPRT to set TESTDIRS to the jtreg test dirs
+JTREG_TESTDIRS = demo/jvmti/gctest demo/jvmti/hprof
+ifdef TESTDIRS
+ JTREG_TESTDIRS = $(TESTDIRS)
+endif
+
+# Default JTREG to run (win32 script works for everybody)
+JTREG = $(JT_HOME)/win32/bin/jtreg
+
+# Option to tell jtreg to not run tests marked with "ignore"
+ifeq ($(PLATFORM), windows)
+ JTREG_KEY_OPTION = -k:!ignore
+else
+ JTREG_KEY_OPTION = -k:\!ignore
+endif
+
+#EXTRA_JTREG_OPTIONS =
-FRC:
+jtreg_tests: prep $(JT_HOME) $(PRODUCT_HOME) $(JTREG)
+ $(JTREG) -a -v:fail,error \
+ $(JTREG_KEY_OPTION) \
+ $(EXTRA_JTREG_OPTIONS) \
+ -r:$(ABS_TEST_OUTPUT_DIR)/JTreport \
+ -w:$(ABS_TEST_OUTPUT_DIR)/JTwork \
+ -jdk:$(PRODUCT_HOME) \
+ $(JAVA_OPTIONS:%=-vmoption:%) \
+ $(JTREG_TESTDIRS) \
+ || $(BUNDLE_UP_FAILED)
+ $(BUNDLE_UP)
+
+PHONY_LIST += jtreg_tests
+
+################################################################
+
+# packtest
+
+# Expect JPRT to set JPRT_PACKTEST_HOME.
+PACKTEST_HOME = /net/jprt-web.sfbay.sun.com/jprt/allproducts/packtest
+ifdef JPRT_PACKTEST_HOME
+ PACKTEST_HOME = $(JPRT_PACKTEST_HOME)
+endif
+#EXTRA_PACKTEST_OPTIONS =
+
+packtest: prep $(PACKTEST_HOME)/ptest $(PRODUCT_HOME)
+ ( $(CD) $(PACKTEST_HOME) && \
+ $(PACKTEST_HOME)/ptest \
+ -t "$(PRODUCT_HOME)" \
+ $(PACKTEST_STRESS_OPTION) \
+ $(EXTRA_PACKTEST_OPTIONS) \
+ -W $(ABS_TEST_OUTPUT_DIR) \
+ $(JAVA_OPTIONS:%=-J %) \
+ ) || $(BUNDLE_UP_FAILED)
+ $(BUNDLE_UP)
+
+packtest_stress: PACKTEST_STRESS_OPTION=-s
+packtest_stress: packtest
+
+PHONY_LIST += packtest packtest_stress
+
+################################################################
+
+# Phony targets (e.g. these are not filenames)
+.PHONY: all clean prep $(PHONY_LIST)
+
+################################################################
+