aboutsummaryrefslogtreecommitdiff
path: root/src/share/vm
diff options
context:
space:
mode:
authorkvn <none@none>2010-02-12 15:27:36 -0800
committerkvn <none@none>2010-02-12 15:27:36 -0800
commit5f7269d8063a500d3c63c4376250a9c0d42e26b3 (patch)
treea0ecf920364c570987bb33afe99c70771bebf6fa /src/share/vm
parent6d82830906c576b8d0c35fe3009846468bce0851 (diff)
parent362fea2bff5f92e417d2f2f28416cf19aa6e46d0 (diff)
Merge
Diffstat (limited to 'src/share/vm')
-rw-r--r--src/share/vm/c1/c1_IR.hpp3
-rw-r--r--src/share/vm/ci/ciMethod.cpp3
-rw-r--r--src/share/vm/code/debugInfoRec.cpp2
-rw-r--r--src/share/vm/code/debugInfoRec.hpp1
-rw-r--r--src/share/vm/code/nmethod.cpp14
-rw-r--r--src/share/vm/code/pcDesc.cpp5
-rw-r--r--src/share/vm/code/pcDesc.hpp4
-rw-r--r--src/share/vm/code/scopeDesc.cpp7
-rw-r--r--src/share/vm/code/scopeDesc.hpp6
-rw-r--r--src/share/vm/includeDB_core1
-rw-r--r--src/share/vm/oops/methodDataOop.hpp23
-rw-r--r--src/share/vm/opto/doCall.cpp4
-rw-r--r--src/share/vm/opto/graphKit.cpp14
-rw-r--r--src/share/vm/opto/loopopts.cpp4
-rw-r--r--src/share/vm/opto/output.cpp8
-rw-r--r--src/share/vm/opto/parse3.cpp16
-rw-r--r--src/share/vm/opto/runtime.cpp2
-rw-r--r--src/share/vm/opto/stringopts.cpp9
-rw-r--r--src/share/vm/prims/jvmtiCodeBlobEvents.cpp2
-rw-r--r--src/share/vm/runtime/arguments.cpp5
-rw-r--r--src/share/vm/runtime/deoptimization.cpp42
-rw-r--r--src/share/vm/runtime/frame.cpp8
-rw-r--r--src/share/vm/runtime/sharedRuntime.cpp9
-rw-r--r--src/share/vm/runtime/vframeArray.cpp7
24 files changed, 141 insertions, 58 deletions
diff --git a/src/share/vm/c1/c1_IR.hpp b/src/share/vm/c1/c1_IR.hpp
index e1af926ae..32ed4a40d 100644
--- a/src/share/vm/c1/c1_IR.hpp
+++ b/src/share/vm/c1/c1_IR.hpp
@@ -253,7 +253,8 @@ class IRScopeDebugInfo: public CompilationResourceObj {
// reexecute allowed only for the topmost frame
bool reexecute = topmost ? should_reexecute() : false;
bool is_method_handle_invoke = false;
- recorder->describe_scope(pc_offset, scope()->method(), bci(), reexecute, is_method_handle_invoke, locvals, expvals, monvals);
+ bool return_oop = false; // This flag will be ignored since it used only for C2 with escape analysis.
+ recorder->describe_scope(pc_offset, scope()->method(), bci(), reexecute, is_method_handle_invoke, return_oop, locvals, expvals, monvals);
}
};
diff --git a/src/share/vm/ci/ciMethod.cpp b/src/share/vm/ci/ciMethod.cpp
index 3d9b04a8e..54a04f8af 100644
--- a/src/share/vm/ci/ciMethod.cpp
+++ b/src/share/vm/ci/ciMethod.cpp
@@ -445,7 +445,8 @@ ciCallProfile ciMethod::call_profile_at_bci(int bci) {
(morphism == ciCallProfile::MorphismLimit && count == 0)) {
#ifdef ASSERT
if (count > 0) {
- tty->print_cr("bci: %d", bci);
+ this->print_short_name(tty);
+ tty->print_cr(" @ bci:%d", bci);
this->print_codes();
assert(false, "this call site should not be polymorphic");
}
diff --git a/src/share/vm/code/debugInfoRec.cpp b/src/share/vm/code/debugInfoRec.cpp
index a1cac2943..14765e4fc 100644
--- a/src/share/vm/code/debugInfoRec.cpp
+++ b/src/share/vm/code/debugInfoRec.cpp
@@ -282,6 +282,7 @@ void DebugInformationRecorder::describe_scope(int pc_offset,
int bci,
bool reexecute,
bool is_method_handle_invoke,
+ bool return_oop,
DebugToken* locals,
DebugToken* expressions,
DebugToken* monitors) {
@@ -296,6 +297,7 @@ void DebugInformationRecorder::describe_scope(int pc_offset,
// Record flags into pcDesc.
last_pd->set_should_reexecute(reexecute);
last_pd->set_is_method_handle_invoke(is_method_handle_invoke);
+ last_pd->set_return_oop(return_oop);
// serialize sender stream offest
stream()->write_int(sender_stream_offset);
diff --git a/src/share/vm/code/debugInfoRec.hpp b/src/share/vm/code/debugInfoRec.hpp
index c67efa09b..8282a051f 100644
--- a/src/share/vm/code/debugInfoRec.hpp
+++ b/src/share/vm/code/debugInfoRec.hpp
@@ -89,6 +89,7 @@ class DebugInformationRecorder: public ResourceObj {
int bci,
bool reexecute,
bool is_method_handle_invoke = false,
+ bool return_oop = false,
DebugToken* locals = NULL,
DebugToken* expressions = NULL,
DebugToken* monitors = NULL);
diff --git a/src/share/vm/code/nmethod.cpp b/src/share/vm/code/nmethod.cpp
index 814a4069f..7ffb0f570 100644
--- a/src/share/vm/code/nmethod.cpp
+++ b/src/share/vm/code/nmethod.cpp
@@ -988,7 +988,8 @@ ScopeDesc* nmethod::scope_desc_at(address pc) {
PcDesc* pd = pc_desc_at(pc);
guarantee(pd != NULL, "scope must be present");
return new ScopeDesc(this, pd->scope_decode_offset(),
- pd->obj_decode_offset(), pd->should_reexecute());
+ pd->obj_decode_offset(), pd->should_reexecute(),
+ pd->return_oop());
}
@@ -2010,7 +2011,10 @@ address nmethod::continuation_for_implicit_exception(address pc) {
print_pcs();
}
#endif
- guarantee(cont_offset != 0, "unhandled implicit exception in compiled code");
+ if (cont_offset == 0) {
+ // Let the normal error handling report the exception
+ return NULL;
+ }
return instructions_begin() + cont_offset;
}
@@ -2156,7 +2160,8 @@ void nmethod::verify_interrupt_point(address call_site) {
PcDesc* pd = pc_desc_at(ic->end_of_call());
assert(pd != NULL, "PcDesc must exist");
for (ScopeDesc* sd = new ScopeDesc(this, pd->scope_decode_offset(),
- pd->obj_decode_offset(), pd->should_reexecute());
+ pd->obj_decode_offset(), pd->should_reexecute(),
+ pd->return_oop());
!sd->is_top(); sd = sd->sender()) {
sd->verify();
}
@@ -2421,7 +2426,8 @@ ScopeDesc* nmethod::scope_desc_in(address begin, address end) {
PcDesc* p = pc_desc_near(begin+1);
if (p != NULL && p->real_pc(this) <= end) {
return new ScopeDesc(this, p->scope_decode_offset(),
- p->obj_decode_offset(), p->should_reexecute());
+ p->obj_decode_offset(), p->should_reexecute(),
+ p->return_oop());
}
return NULL;
}
diff --git a/src/share/vm/code/pcDesc.cpp b/src/share/vm/code/pcDesc.cpp
index 5b981645a..5d6456bf5 100644
--- a/src/share/vm/code/pcDesc.cpp
+++ b/src/share/vm/code/pcDesc.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2010 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
@@ -52,7 +52,8 @@ void PcDesc::print(nmethod* code) {
tty->print(" ");
sd->method()->print_short_name(tty);
tty->print(" @%d", sd->bci());
- tty->print(" reexecute=%s", sd->should_reexecute()?"true":"false");
+ if (sd->should_reexecute())
+ tty->print(" reexecute=true");
tty->cr();
}
#endif
diff --git a/src/share/vm/code/pcDesc.hpp b/src/share/vm/code/pcDesc.hpp
index 74d3baaf2..c66681061 100644
--- a/src/share/vm/code/pcDesc.hpp
+++ b/src/share/vm/code/pcDesc.hpp
@@ -39,6 +39,7 @@ class PcDesc VALUE_OBJ_CLASS_SPEC {
struct {
unsigned int reexecute: 1;
unsigned int is_method_handle_invoke: 1;
+ unsigned int return_oop: 1;
} bits;
bool operator ==(const PcDescFlags& other) { return word == other.word; }
} _flags;
@@ -76,6 +77,9 @@ class PcDesc VALUE_OBJ_CLASS_SPEC {
bool is_method_handle_invoke() const { return _flags.bits.is_method_handle_invoke; }
void set_is_method_handle_invoke(bool z) { _flags.bits.is_method_handle_invoke = z; }
+ bool return_oop() const { return _flags.bits.return_oop; }
+ void set_return_oop(bool z) { _flags.bits.return_oop = z; }
+
// Returns the real pc
address real_pc(const nmethod* code) const;
diff --git a/src/share/vm/code/scopeDesc.cpp b/src/share/vm/code/scopeDesc.cpp
index a034530e6..5b411c5be 100644
--- a/src/share/vm/code/scopeDesc.cpp
+++ b/src/share/vm/code/scopeDesc.cpp
@@ -26,19 +26,21 @@
# include "incls/_scopeDesc.cpp.incl"
-ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute) {
+ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool return_oop) {
_code = code;
_decode_offset = decode_offset;
_objects = decode_object_values(obj_decode_offset);
_reexecute = reexecute;
+ _return_oop = return_oop;
decode_body();
}
-ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, bool reexecute) {
+ScopeDesc::ScopeDesc(const nmethod* code, int decode_offset, bool reexecute, bool return_oop) {
_code = code;
_decode_offset = decode_offset;
_objects = decode_object_values(DebugInformationRecorder::serialized_null);
_reexecute = reexecute;
+ _return_oop = return_oop;
decode_body();
}
@@ -48,6 +50,7 @@ ScopeDesc::ScopeDesc(const ScopeDesc* parent) {
_decode_offset = parent->_sender_decode_offset;
_objects = parent->_objects;
_reexecute = false; //reexecute only applies to the first scope
+ _return_oop = false;
decode_body();
}
diff --git a/src/share/vm/code/scopeDesc.hpp b/src/share/vm/code/scopeDesc.hpp
index d030eaea8..345769ae5 100644
--- a/src/share/vm/code/scopeDesc.hpp
+++ b/src/share/vm/code/scopeDesc.hpp
@@ -52,17 +52,18 @@ class SimpleScopeDesc : public StackObj {
class ScopeDesc : public ResourceObj {
public:
// Constructor
- ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute);
+ ScopeDesc(const nmethod* code, int decode_offset, int obj_decode_offset, bool reexecute, bool return_oop);
// Calls above, giving default value of "serialized_null" to the
// "obj_decode_offset" argument. (We don't use a default argument to
// avoid a .hpp-.hpp dependency.)
- ScopeDesc(const nmethod* code, int decode_offset, bool reexecute);
+ ScopeDesc(const nmethod* code, int decode_offset, bool reexecute, bool return_oop);
// JVM state
methodHandle method() const { return _method; }
int bci() const { return _bci; }
bool should_reexecute() const { return _reexecute; }
+ bool return_oop() const { return _return_oop; }
GrowableArray<ScopeValue*>* locals();
GrowableArray<ScopeValue*>* expressions();
@@ -88,6 +89,7 @@ class ScopeDesc : public ResourceObj {
methodHandle _method;
int _bci;
bool _reexecute;
+ bool _return_oop;
// Decoding offsets
int _decode_offset;
diff --git a/src/share/vm/includeDB_core b/src/share/vm/includeDB_core
index 675a6657e..a3e06d2f9 100644
--- a/src/share/vm/includeDB_core
+++ b/src/share/vm/includeDB_core
@@ -1484,6 +1484,7 @@ deoptimization.cpp thread.hpp
deoptimization.cpp vframe.hpp
deoptimization.cpp vframeArray.hpp
deoptimization.cpp vframe_hp.hpp
+deoptimization.cpp vmreg_<arch>.inline.hpp
deoptimization.cpp xmlstream.hpp
deoptimization.hpp allocation.hpp
diff --git a/src/share/vm/oops/methodDataOop.hpp b/src/share/vm/oops/methodDataOop.hpp
index e1c8eaf10..ca585f8b6 100644
--- a/src/share/vm/oops/methodDataOop.hpp
+++ b/src/share/vm/oops/methodDataOop.hpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2000-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2000-2010 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
@@ -545,6 +545,10 @@ public:
return cell_offset(counter_cell_count);
}
+ void set_count(uint count) {
+ set_uint_at(count_off, count);
+ }
+
#ifndef PRODUCT
void print_data_on(outputStream* st);
#endif
@@ -692,6 +696,23 @@ public:
void clear_row(uint row) {
assert(row < row_limit(), "oob");
+ // Clear total count - indicator of polymorphic call site.
+ // The site may look like as monomorphic after that but
+ // it allow to have more accurate profiling information because
+ // there was execution phase change since klasses were unloaded.
+ // If the site is still polymorphic then MDO will be updated
+ // to reflect it. But it could be the case that the site becomes
+ // only bimorphic. Then keeping total count not 0 will be wrong.
+ // Even if we use monomorphic (when it is not) for compilation
+ // we will only have trap, deoptimization and recompile again
+ // with updated MDO after executing method in Interpreter.
+ // An additional receiver will be recorded in the cleaned row
+ // during next call execution.
+ //
+ // Note: our profiling logic works with empty rows in any slot.
+ // We do sorting a profiling info (ciCallProfile) for compilation.
+ //
+ set_count(0);
set_receiver(row, NULL);
set_receiver_count(row, 0);
}
diff --git a/src/share/vm/opto/doCall.cpp b/src/share/vm/opto/doCall.cpp
index d9c1a23bd..2f3f734fd 100644
--- a/src/share/vm/opto/doCall.cpp
+++ b/src/share/vm/opto/doCall.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 1998-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1998-2010 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
@@ -70,7 +70,7 @@ CallGenerator* Compile::call_generator(ciMethod* call_method, int vtable_index,
CompileLog* log = this->log();
if (log != NULL) {
int rid = (receiver_count >= 0)? log->identify(profile.receiver(0)): -1;
- int r2id = (profile.morphism() == 2)? log->identify(profile.receiver(1)):-1;
+ int r2id = (rid != -1 && profile.has_receiver(1))? log->identify(profile.receiver(1)):-1;
log->begin_elem("call method='%d' count='%d' prof_factor='%g'",
log->identify(call_method), site_count, prof_factor);
if (call_is_virtual) log->print(" virtual='1'");
diff --git a/src/share/vm/opto/graphKit.cpp b/src/share/vm/opto/graphKit.cpp
index d70fe1eef..3d5505514 100644
--- a/src/share/vm/opto/graphKit.cpp
+++ b/src/share/vm/opto/graphKit.cpp
@@ -780,12 +780,20 @@ bool GraphKit::dead_locals_are_killed() {
// Helper function for enforcing certain bytecodes to reexecute if
// deoptimization happens
-static bool should_reexecute_implied_by_bytecode(JVMState *jvms) {
+static bool should_reexecute_implied_by_bytecode(JVMState *jvms, bool is_anewarray) {
ciMethod* cur_method = jvms->method();
int cur_bci = jvms->bci();
if (cur_method != NULL && cur_bci != InvocationEntryBci) {
Bytecodes::Code code = cur_method->java_code_at_bci(cur_bci);
- return Interpreter::bytecode_should_reexecute(code);
+ return Interpreter::bytecode_should_reexecute(code) ||
+ is_anewarray && code == Bytecodes::_multianewarray;
+ // Reexecute _multianewarray bytecode which was replaced with
+ // sequence of [a]newarray. See Parse::do_multianewarray().
+ //
+ // Note: interpreter should not have it set since this optimization
+ // is limited by dimensions and guarded by flag so in some cases
+ // multianewarray() runtime calls will be generated and
+ // the bytecode should not be reexecutes (stack will not be reset).
} else
return false;
}
@@ -836,7 +844,7 @@ void GraphKit::add_safepoint_edges(SafePointNode* call, bool must_throw) {
// For a known set of bytecodes, the interpreter should reexecute them if
// deoptimization happens. We set the reexecute state for them here
if (out_jvms->is_reexecute_undefined() && //don't change if already specified
- should_reexecute_implied_by_bytecode(out_jvms)) {
+ should_reexecute_implied_by_bytecode(out_jvms, call->is_AllocateArray())) {
out_jvms->set_should_reexecute(true); //NOTE: youngest_jvms not changed
}
diff --git a/src/share/vm/opto/loopopts.cpp b/src/share/vm/opto/loopopts.cpp
index 68e5f468c..05295751f 100644
--- a/src/share/vm/opto/loopopts.cpp
+++ b/src/share/vm/opto/loopopts.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 1999-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1999-2010 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
@@ -47,7 +47,7 @@ Node *PhaseIdealLoop::split_thru_phi( Node *n, Node *region, int policy ) {
int offset = t_oop->offset();
phi = new (C,region->req()) PhiNode(region, type, NULL, iid, index, offset);
} else {
- phi = new (C,region->req()) PhiNode(region, type);
+ phi = PhiNode::make_blank(region, n);
}
uint old_unique = C->unique();
for( uint i = 1; i < region->req(); i++ ) {
diff --git a/src/share/vm/opto/output.cpp b/src/share/vm/opto/output.cpp
index 65cc41b18..deb2ac2c3 100644
--- a/src/share/vm/opto/output.cpp
+++ b/src/share/vm/opto/output.cpp
@@ -795,6 +795,7 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) {
int safepoint_pc_offset = current_offset;
bool is_method_handle_invoke = false;
+ bool return_oop = false;
// Add the safepoint in the DebugInfoRecorder
if( !mach->is_MachCall() ) {
@@ -807,6 +808,11 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) {
if (mcall->is_MachCallJava())
is_method_handle_invoke = mcall->as_MachCallJava()->_method_handle_invoke;
+ // Check if a call returns an object.
+ if (mcall->return_value_is_used() &&
+ mcall->tf()->range()->field_at(TypeFunc::Parms)->isa_ptr()) {
+ return_oop = true;
+ }
safepoint_pc_offset += mcall->ret_addr_offset();
debug_info()->add_safepoint(safepoint_pc_offset, mcall->_oop_map);
}
@@ -919,7 +925,7 @@ void Compile::Process_OopMap_Node(MachNode *mach, int current_offset) {
assert(jvms->bci() >= InvocationEntryBci && jvms->bci() <= 0x10000, "must be a valid or entry BCI");
assert(!jvms->should_reexecute() || depth == max_depth, "reexecute allowed only for the youngest");
// Now we can describe the scope.
- debug_info()->describe_scope(safepoint_pc_offset, scope_method, jvms->bci(), jvms->should_reexecute(), is_method_handle_invoke, locvals, expvals, monvals);
+ debug_info()->describe_scope(safepoint_pc_offset, scope_method, jvms->bci(), jvms->should_reexecute(), is_method_handle_invoke, return_oop, locvals, expvals, monvals);
} // End jvms loop
// Mark the end of the scope set.
diff --git a/src/share/vm/opto/parse3.cpp b/src/share/vm/opto/parse3.cpp
index 40f9940bd..9f0a034bb 100644
--- a/src/share/vm/opto/parse3.cpp
+++ b/src/share/vm/opto/parse3.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 1998-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1998-2010 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
@@ -439,8 +439,18 @@ void Parse::do_multianewarray() {
// Can use multianewarray instead of [a]newarray if only one dimension,
// or if all non-final dimensions are small constants.
- if (expand_count == 1 || (1 <= expand_count && expand_count <= expand_limit)) {
- Node* obj = expand_multianewarray(array_klass, &length[0], ndimensions, ndimensions);
+ if (ndimensions == 1 || (1 <= expand_count && expand_count <= expand_limit)) {
+ Node* obj = NULL;
+ // Set the original stack and the reexecute bit for the interpreter
+ // to reexecute the multianewarray bytecode if deoptimization happens.
+ // Do it unconditionally even for one dimension multianewarray.
+ // Note: the reexecute bit will be set in GraphKit::add_safepoint_edges()
+ // when AllocateArray node for newarray is created.
+ { PreserveReexecuteState preexecs(this);
+ _sp += ndimensions;
+ // Pass 0 as nargs since uncommon trap code does not need to restore stack.
+ obj = expand_multianewarray(array_klass, &length[0], ndimensions, 0);
+ } //original reexecute and sp are set back here
push(obj);
return;
}
diff --git a/src/share/vm/opto/runtime.cpp b/src/share/vm/opto/runtime.cpp
index 055622509..c2d5ca7df 100644
--- a/src/share/vm/opto/runtime.cpp
+++ b/src/share/vm/opto/runtime.cpp
@@ -708,7 +708,7 @@ JRT_LEAF(void, OptoRuntime::profile_receiver_type_C(DataLayout* data, oopDesc* r
*(mdp + count_off) = DataLayout::counter_increment;
} else {
// Receiver did not match any saved receiver and there is no empty row for it.
- // Increment total counter to indicate polimorphic case.
+ // Increment total counter to indicate polymorphic case.
intptr_t* count_p = (intptr_t*)(((byte*)(data)) + in_bytes(CounterData::count_offset()));
*count_p += DataLayout::counter_increment;
}
diff --git a/src/share/vm/opto/stringopts.cpp b/src/share/vm/opto/stringopts.cpp
index 192d31f82..01476453b 100644
--- a/src/share/vm/opto/stringopts.cpp
+++ b/src/share/vm/opto/stringopts.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 2009-2010 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
@@ -1073,7 +1073,7 @@ void PhaseStringOpts::int_getChars(GraphKit& kit, Node* arg, Node* char_array, N
kit.set_control(head);
kit.set_memory(mem, char_adr_idx);
- Node* q = __ DivI(kit.null(), i_phi, __ intcon(10));
+ Node* q = __ DivI(NULL, i_phi, __ intcon(10));
Node* r = __ SubI(i_phi, __ AddI(__ LShiftI(q, __ intcon(3)),
__ LShiftI(q, __ intcon(1))));
Node* m1 = __ SubI(charPos, __ intcon(1));
@@ -1270,14 +1270,15 @@ void PhaseStringOpts::replace_string_concat(StringConcat* sc) {
// length = length + (s.count - s.offset);
RegionNode *r = new (C, 3) RegionNode(3);
kit.gvn().set_type(r, Type::CONTROL);
- Node *phi = new (C, 3) PhiNode(r, type->join(TypeInstPtr::NOTNULL));
+ Node *phi = new (C, 3) PhiNode(r, type);
kit.gvn().set_type(phi, phi->bottom_type());
Node* p = __ Bool(__ CmpP(arg, kit.null()), BoolTest::ne);
IfNode* iff = kit.create_and_map_if(kit.control(), p, PROB_MIN, COUNT_UNKNOWN);
Node* notnull = __ IfTrue(iff);
Node* isnull = __ IfFalse(iff);
+ kit.set_control(notnull); // set control for the cast_not_null
r->init_req(1, notnull);
- phi->init_req(1, arg);
+ phi->init_req(1, kit.cast_not_null(arg, false));
r->init_req(2, isnull);
phi->init_req(2, null_string);
kit.set_control(r);
diff --git a/src/share/vm/prims/jvmtiCodeBlobEvents.cpp b/src/share/vm/prims/jvmtiCodeBlobEvents.cpp
index 93217303f..d09bf8152 100644
--- a/src/share/vm/prims/jvmtiCodeBlobEvents.cpp
+++ b/src/share/vm/prims/jvmtiCodeBlobEvents.cpp
@@ -402,7 +402,7 @@ void JvmtiCodeBlobEvents::build_jvmti_addr_location_map(nmethod *nm,
address scopes_data = nm->scopes_data_begin();
for( pcd = nm->scopes_pcs_begin(); pcd < nm->scopes_pcs_end(); ++pcd ) {
- ScopeDesc sc0(nm, pcd->scope_decode_offset(), pcd->should_reexecute());
+ ScopeDesc sc0(nm, pcd->scope_decode_offset(), pcd->should_reexecute(), pcd->return_oop());
ScopeDesc *sd = &sc0;
while( !sd->is_top() ) { sd = sd->sender(); }
int bci = sd->bci();
diff --git a/src/share/vm/runtime/arguments.cpp b/src/share/vm/runtime/arguments.cpp
index 66d84c5c4..f8e9a85ab 100644
--- a/src/share/vm/runtime/arguments.cpp
+++ b/src/share/vm/runtime/arguments.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2010 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
@@ -2524,6 +2524,9 @@ jint Arguments::finalize_vm_init_args(SysClassPath* scp_p, bool scp_assembly_req
SOLARIS_ONLY(FLAG_SET_DEFAULT(UseISM, false));
}
+ // Tiered compilation is undefined with C1.
+ TieredCompilation = false;
+
#else
if (!FLAG_IS_DEFAULT(OptoLoopAlignment) && FLAG_IS_DEFAULT(MaxLoopPad)) {
FLAG_SET_DEFAULT(MaxLoopPad, OptoLoopAlignment-1);
diff --git a/src/share/vm/runtime/deoptimization.cpp b/src/share/vm/runtime/deoptimization.cpp
index 6a8f8e122..d3d60d915 100644
--- a/src/share/vm/runtime/deoptimization.cpp
+++ b/src/share/vm/runtime/deoptimization.cpp
@@ -145,6 +145,27 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
if (EliminateAllocations) {
assert (chunk->at(0)->scope() != NULL,"expect only compiled java frames");
GrowableArray<ScopeValue*>* objects = chunk->at(0)->scope()->objects();
+
+ // The flag return_oop() indicates call sites which return oop
+ // in compiled code. Such sites include java method calls,
+ // runtime calls (for example, used to allocate new objects/arrays
+ // on slow code path) and any other calls generated in compiled code.
+ // It is not guaranteed that we can get such information here only
+ // by analyzing bytecode in deoptimized frames. This is why this flag
+ // is set during method compilation (see Compile::Process_OopMap_Node()).
+ bool save_oop_result = chunk->at(0)->scope()->return_oop();
+ Handle return_value;
+ if (save_oop_result) {
+ // Reallocation may trigger GC. If deoptimization happened on return from
+ // call which returns oop we need to save it since it is not in oopmap.
+ oop result = deoptee.saved_oop_result(&map);
+ assert(result == NULL || result->is_oop(), "must be oop");
+ return_value = Handle(thread, result);
+ assert(Universe::heap()->is_in_or_null(result), "must be heap pointer");
+ if (TraceDeoptimization) {
+ tty->print_cr("SAVED OOP RESULT " INTPTR_FORMAT " in thread " INTPTR_FORMAT, result, thread);
+ }
+ }
bool reallocated = false;
if (objects != NULL) {
JRT_BLOCK
@@ -158,9 +179,13 @@ Deoptimization::UnrollBlock* Deoptimization::fetch_unroll_info_helper(JavaThread
ttyLocker ttyl;
tty->print_cr("REALLOC OBJECTS in thread " INTPTR_FORMAT, thread);
print_objects(objects);
- }
+ }
#endif
}
+ if (save_oop_result) {
+ // Restore result.
+ deoptee.set_saved_oop_result(&map, return_value());
+ }
}
if (EliminateLocks) {
#ifndef PRODUCT
@@ -913,21 +938,6 @@ vframeArray* Deoptimization::create_vframeArray(JavaThread* thread, frame fr, Re
if (TraceDeoptimization) {
ttyLocker ttyl;
tty->print_cr(" Created vframeArray " INTPTR_FORMAT, array);
- if (Verbose) {
- int count = 0;
- // this used to leak deoptimizedVFrame like it was going out of style!!!
- for (int index = 0; index < array->frames(); index++ ) {
- vframeArrayElement* e = array->element(index);
- e->print(tty);
-
- /*
- No printing yet.
- array->vframe_at(index)->print_activation(count++);
- // better as...
- array->print_activation_for(index, count++);
- */
- }
- }
}
#endif // PRODUCT
diff --git a/src/share/vm/runtime/frame.cpp b/src/share/vm/runtime/frame.cpp
index 5844107c5..30782f355 100644
--- a/src/share/vm/runtime/frame.cpp
+++ b/src/share/vm/runtime/frame.cpp
@@ -606,12 +606,12 @@ void frame::interpreter_frame_print_on(outputStream* st) const {
for (BasicObjectLock* current = interpreter_frame_monitor_end();
current < interpreter_frame_monitor_begin();
current = next_monitor_in_interpreter_frame(current)) {
- st->print_cr(" [ - obj ");
+ st->print(" - obj [");
current->obj()->print_value_on(st);
- st->cr();
- st->print_cr(" - lock ");
+ st->print_cr("]");
+ st->print(" - lock [");
current->lock()->print_on(st);
- st->cr();
+ st->print_cr("]");
}
// monitor
st->print_cr(" - monitor[" INTPTR_FORMAT "]", interpreter_frame_monitor_begin());
diff --git a/src/share/vm/runtime/sharedRuntime.cpp b/src/share/vm/runtime/sharedRuntime.cpp
index 4bbdd4573..309862585 100644
--- a/src/share/vm/runtime/sharedRuntime.cpp
+++ b/src/share/vm/runtime/sharedRuntime.cpp
@@ -607,7 +607,9 @@ address SharedRuntime::continuation_for_implicit_exception(JavaThread* thread,
_implicit_null_throws++;
#endif
target_pc = nm->continuation_for_implicit_exception(pc);
- guarantee(target_pc != 0, "must have a continuation point");
+ // If there's an unexpected fault, target_pc might be NULL,
+ // in which case we want to fall through into the normal
+ // error handling code.
}
break; // fall through
@@ -621,14 +623,15 @@ address SharedRuntime::continuation_for_implicit_exception(JavaThread* thread,
_implicit_div0_throws++;
#endif
target_pc = nm->continuation_for_implicit_exception(pc);
- guarantee(target_pc != 0, "must have a continuation point");
+ // If there's an unexpected fault, target_pc might be NULL,
+ // in which case we want to fall through into the normal
+ // error handling code.
break; // fall through
}
default: ShouldNotReachHere();
}
- guarantee(target_pc != NULL, "must have computed destination PC for implicit exception");
assert(exception_kind == IMPLICIT_NULL || exception_kind == IMPLICIT_DIVIDE_BY_ZERO, "wrong implicit exception kind");
// for AbortVMOnException flag
diff --git a/src/share/vm/runtime/vframeArray.cpp b/src/share/vm/runtime/vframeArray.cpp
index 3f507d217..6a9aac2ef 100644
--- a/src/share/vm/runtime/vframeArray.cpp
+++ b/src/share/vm/runtime/vframeArray.cpp
@@ -1,5 +1,5 @@
/*
- * Copyright 1997-2009 Sun Microsystems, Inc. All Rights Reserved.
+ * Copyright 1997-2010 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
@@ -186,7 +186,7 @@ void vframeArrayElement::unpack_on_stack(int callee_parameters,
int popframe_preserved_args_size_in_bytes = 0;
int popframe_preserved_args_size_in_words = 0;
if (is_top_frame) {
- JvmtiThreadState *state = thread->jvmti_thread_state();
+ JvmtiThreadState *state = thread->jvmti_thread_state();
if (JvmtiExport::can_pop_frame() &&
(thread->has_pending_popframe() || thread->popframe_forcing_deopt_reexecution())) {
if (thread->has_pending_popframe()) {
@@ -381,7 +381,6 @@ void vframeArrayElement::unpack_on_stack(int callee_parameters,
RegisterMap map(thread);
vframe* f = vframe::new_vframe(iframe(), &map, thread);
f->print();
- iframe()->interpreter_frame_print_on(tty);
tty->print_cr("locals size %d", locals()->size());
tty->print_cr("expression size %d", expressions()->size());
@@ -582,7 +581,7 @@ void vframeArray::print_on_2(outputStream* st) {
}
void vframeArrayElement::print(outputStream* st) {
- st->print_cr(" - interpreter_frame -> sp: ", INTPTR_FORMAT, iframe()->sp());
+ st->print_cr(" - interpreter_frame -> sp: " INTPTR_FORMAT, iframe()->sp());
}
void vframeArray::print_value_on(outputStream* st) const {