--- a/hotspot/src/share/vm/opto/stringopts.cpp Mon Dec 17 11:00:22 2012 -0800
+++ b/hotspot/src/share/vm/opto/stringopts.cpp Tue Dec 18 14:55:25 2012 +0100
@@ -744,7 +744,9 @@
ctrl_path.push(cn);
ctrl_path.push(cn->proj_out(0));
ctrl_path.push(cn->proj_out(0)->unique_out());
- ctrl_path.push(cn->proj_out(0)->unique_out()->as_Catch()->proj_out(0));
+ if (cn->proj_out(0)->unique_out()->as_Catch()->proj_out(0) != NULL) {
+ ctrl_path.push(cn->proj_out(0)->unique_out()->as_Catch()->proj_out(0));
+ }
} else {
ShouldNotReachHere();
}
@@ -762,6 +764,12 @@
} else if (ptr->is_IfTrue()) {
IfNode* iff = ptr->in(0)->as_If();
BoolNode* b = iff->in(1)->isa_Bool();
+
+ if (b == NULL) {
+ fail = true;
+ break;
+ }
+
Node* cmp = b->in(1);
Node* v1 = cmp->in(1);
Node* v2 = cmp->in(2);
@@ -1408,71 +1416,76 @@
Deoptimization::Action_make_not_entrant);
}
- // length now contains the number of characters needed for the
- // char[] so create a new AllocateArray for the char[]
- Node* char_array = NULL;
- {
- PreserveReexecuteState preexecs(&kit);
- // The original jvms is for an allocation of either a String or
- // StringBuffer so no stack adjustment is necessary for proper
- // reexecution. If we deoptimize in the slow path the bytecode
- // will be reexecuted and the char[] allocation will be thrown away.
- kit.jvms()->set_should_reexecute(true);
- char_array = kit.new_array(__ makecon(TypeKlassPtr::make(ciTypeArrayKlass::make(T_CHAR))),
- length, 1);
- }
+ Node* result;
+ if (!kit.stopped()) {
+
+ // length now contains the number of characters needed for the
+ // char[] so create a new AllocateArray for the char[]
+ Node* char_array = NULL;
+ {
+ PreserveReexecuteState preexecs(&kit);
+ // The original jvms is for an allocation of either a String or
+ // StringBuffer so no stack adjustment is necessary for proper
+ // reexecution. If we deoptimize in the slow path the bytecode
+ // will be reexecuted and the char[] allocation will be thrown away.
+ kit.jvms()->set_should_reexecute(true);
+ char_array = kit.new_array(__ makecon(TypeKlassPtr::make(ciTypeArrayKlass::make(T_CHAR))),
+ length, 1);
+ }
+
+ // Mark the allocation so that zeroing is skipped since the code
+ // below will overwrite the entire array
+ AllocateArrayNode* char_alloc = AllocateArrayNode::Ideal_array_allocation(char_array, _gvn);
+ char_alloc->maybe_set_complete(_gvn);
- // Mark the allocation so that zeroing is skipped since the code
- // below will overwrite the entire array
- AllocateArrayNode* char_alloc = AllocateArrayNode::Ideal_array_allocation(char_array, _gvn);
- char_alloc->maybe_set_complete(_gvn);
-
- // Now copy the string representations into the final char[]
- Node* start = __ intcon(0);
- for (int argi = 0; argi < sc->num_arguments(); argi++) {
- Node* arg = sc->argument(argi);
- switch (sc->mode(argi)) {
- case StringConcat::IntMode: {
- Node* end = __ AddI(start, string_sizes->in(argi));
- // getChars words backwards so pass the ending point as well as the start
- int_getChars(kit, arg, char_array, start, end);
- start = end;
- break;
+ // Now copy the string representations into the final char[]
+ Node* start = __ intcon(0);
+ for (int argi = 0; argi < sc->num_arguments(); argi++) {
+ Node* arg = sc->argument(argi);
+ switch (sc->mode(argi)) {
+ case StringConcat::IntMode: {
+ Node* end = __ AddI(start, string_sizes->in(argi));
+ // getChars words backwards so pass the ending point as well as the start
+ int_getChars(kit, arg, char_array, start, end);
+ start = end;
+ break;
+ }
+ case StringConcat::StringNullCheckMode:
+ case StringConcat::StringMode: {
+ start = copy_string(kit, arg, char_array, start);
+ break;
+ }
+ case StringConcat::CharMode: {
+ __ store_to_memory(kit.control(), kit.array_element_address(char_array, start, T_CHAR),
+ arg, T_CHAR, char_adr_idx);
+ start = __ AddI(start, __ intcon(1));
+ break;
+ }
+ default:
+ ShouldNotReachHere();
}
- case StringConcat::StringNullCheckMode:
- case StringConcat::StringMode: {
- start = copy_string(kit, arg, char_array, start);
- break;
- }
- case StringConcat::CharMode: {
- __ store_to_memory(kit.control(), kit.array_element_address(char_array, start, T_CHAR),
- arg, T_CHAR, char_adr_idx);
- start = __ AddI(start, __ intcon(1));
- break;
- }
- default:
- ShouldNotReachHere();
}
- }
- // If we're not reusing an existing String allocation then allocate one here.
- Node* result = sc->string_alloc();
- if (result == NULL) {
- PreserveReexecuteState preexecs(&kit);
- // The original jvms is for an allocation of either a String or
- // StringBuffer so no stack adjustment is necessary for proper
- // reexecution.
- kit.jvms()->set_should_reexecute(true);
- result = kit.new_instance(__ makecon(TypeKlassPtr::make(C->env()->String_klass())));
+ // If we're not reusing an existing String allocation then allocate one here.
+ result = sc->string_alloc();
+ if (result == NULL) {
+ PreserveReexecuteState preexecs(&kit);
+ // The original jvms is for an allocation of either a String or
+ // StringBuffer so no stack adjustment is necessary for proper
+ // reexecution.
+ kit.jvms()->set_should_reexecute(true);
+ result = kit.new_instance(__ makecon(TypeKlassPtr::make(C->env()->String_klass())));
+ }
+
+ // Intialize the string
+ if (java_lang_String::has_offset_field()) {
+ kit.store_String_offset(kit.control(), result, __ intcon(0));
+ kit.store_String_length(kit.control(), result, length);
+ }
+ kit.store_String_value(kit.control(), result, char_array);
+ } else {
+ result = C->top();
}
-
- // Intialize the string
- if (java_lang_String::has_offset_field()) {
- kit.store_String_offset(kit.control(), result, __ intcon(0));
- kit.store_String_length(kit.control(), result, length);
- }
- kit.store_String_value(kit.control(), result, char_array);
-
// hook up the outgoing control and result
kit.replace_call(sc->end(), result);