src/share/vm/c1/c1_GraphBuilder.cpp

Print this page
rev 5932 : 8035493: JVMTI PopFrame capability must instruct compilers not to prune locals
Reviewed-by:


2259     Constant* con = value->as_Constant();
2260     if (con) {
2261       ObjectType* c = con->type()->as_ObjectType();
2262       if (c && c->is_loaded()) {
2263         ObjectConstant* oc = c->as_ObjectConstant();
2264         if (!oc || !oc->value()->is_null_object()) {
2265           return;
2266         }
2267       }
2268     }
2269   }
2270   append(new NullCheck(value, copy_state_for_exception()));
2271 }
2272 
2273 
2274 
2275 XHandlers* GraphBuilder::handle_exception(Instruction* instruction) {
2276   if (!has_handler() && (!instruction->needs_exception_state() || instruction->exception_state() != NULL)) {
2277     assert(instruction->exception_state() == NULL
2278            || instruction->exception_state()->kind() == ValueStack::EmptyExceptionState
2279            || (instruction->exception_state()->kind() == ValueStack::ExceptionState && _compilation->env()->jvmti_can_access_local_variables()),
2280            "exception_state should be of exception kind");
2281     return new XHandlers();
2282   }
2283 
2284   XHandlers*  exception_handlers = new XHandlers();
2285   ScopeData*  cur_scope_data = scope_data();
2286   ValueStack* cur_state = instruction->state_before();
2287   ValueStack* prev_state = NULL;
2288   int scope_count = 0;
2289 
2290   assert(cur_state != NULL, "state_before must be set");
2291   do {
2292     int cur_bci = cur_state->bci();
2293     assert(cur_scope_data->scope() == cur_state->scope(), "scopes do not match");
2294     assert(cur_bci == SynchronizationEntryBCI || cur_bci == cur_scope_data->stream()->cur_bci(), "invalid bci");
2295 
2296     // join with all potential exception handlers
2297     XHandlers* list = cur_scope_data->xhandlers();
2298     const int n = list->length();
2299     for (int i = 0; i < n; i++) {


2350         XHandler* new_xhandler = new XHandler(h);
2351         new_xhandler->set_phi_operand(phi_operand);
2352         new_xhandler->set_scope_count(scope_count);
2353         exception_handlers->append(new_xhandler);
2354 
2355         // fill in exception handler subgraph lazily
2356         assert(!entry->is_set(BlockBegin::was_visited_flag), "entry must not be visited yet");
2357         cur_scope_data->add_to_work_list(entry);
2358 
2359         // stop when reaching catchall
2360         if (h->catch_type() == 0) {
2361           return exception_handlers;
2362         }
2363       }
2364     }
2365 
2366     if (exception_handlers->length() == 0) {
2367       // This scope and all callees do not handle exceptions, so the local
2368       // variables of this scope are not needed. However, the scope itself is
2369       // required for a correct exception stack trace -> clear out the locals.
2370       if (_compilation->env()->jvmti_can_access_local_variables()) {
2371         cur_state = cur_state->copy(ValueStack::ExceptionState, cur_state->bci());
2372       } else {
2373         cur_state = cur_state->copy(ValueStack::EmptyExceptionState, cur_state->bci());
2374       }
2375       if (prev_state != NULL) {
2376         prev_state->set_caller_state(cur_state);
2377       }
2378       if (instruction->exception_state() == NULL) {
2379         instruction->set_exception_state(cur_state);
2380       }
2381     }
2382 
2383     // Set up iteration for next time.
2384     // If parsing a jsr, do not grab exception handlers from the
2385     // parent scopes for this method (already got them, and they
2386     // needed to be cloned)
2387 
2388     while (cur_scope_data->parsing_jsr()) {
2389       cur_scope_data = cur_scope_data->parent();
2390     }


3234 ValueStack* GraphBuilder::copy_state_exhandling() {
3235   return copy_state_exhandling_with_bci(bci());
3236 }
3237 
3238 ValueStack* GraphBuilder::copy_state_for_exception() {
3239   return copy_state_for_exception_with_bci(bci());
3240 }
3241 
3242 ValueStack* GraphBuilder::copy_state_before_with_bci(int bci) {
3243   return state()->copy(ValueStack::StateBefore, bci);
3244 }
3245 
3246 ValueStack* GraphBuilder::copy_state_exhandling_with_bci(int bci) {
3247   if (!has_handler()) return NULL;
3248   return state()->copy(ValueStack::StateBefore, bci);
3249 }
3250 
3251 ValueStack* GraphBuilder::copy_state_for_exception_with_bci(int bci) {
3252   ValueStack* s = copy_state_exhandling_with_bci(bci);
3253   if (s == NULL) {
3254     if (_compilation->env()->jvmti_can_access_local_variables()) {
3255       s = state()->copy(ValueStack::ExceptionState, bci);
3256     } else {
3257       s = state()->copy(ValueStack::EmptyExceptionState, bci);
3258     }
3259   }
3260   return s;
3261 }
3262 
3263 int GraphBuilder::recursive_inline_level(ciMethod* cur_callee) const {
3264   int recur_level = 0;
3265   for (IRScope* s = scope(); s != NULL; s = s->caller()) {
3266     if (s->method() == cur_callee) {
3267       ++recur_level;
3268     }
3269   }
3270   return recur_level;
3271 }
3272 
3273 
3274 bool GraphBuilder::try_inline(ciMethod* callee, bool holder_known, Bytecodes::Code bc, Value receiver) {




2259     Constant* con = value->as_Constant();
2260     if (con) {
2261       ObjectType* c = con->type()->as_ObjectType();
2262       if (c && c->is_loaded()) {
2263         ObjectConstant* oc = c->as_ObjectConstant();
2264         if (!oc || !oc->value()->is_null_object()) {
2265           return;
2266         }
2267       }
2268     }
2269   }
2270   append(new NullCheck(value, copy_state_for_exception()));
2271 }
2272 
2273 
2274 
2275 XHandlers* GraphBuilder::handle_exception(Instruction* instruction) {
2276   if (!has_handler() && (!instruction->needs_exception_state() || instruction->exception_state() != NULL)) {
2277     assert(instruction->exception_state() == NULL
2278            || instruction->exception_state()->kind() == ValueStack::EmptyExceptionState
2279            || (instruction->exception_state()->kind() == ValueStack::ExceptionState && _compilation->env()->should_retain_local_variables()),
2280            "exception_state should be of exception kind");
2281     return new XHandlers();
2282   }
2283 
2284   XHandlers*  exception_handlers = new XHandlers();
2285   ScopeData*  cur_scope_data = scope_data();
2286   ValueStack* cur_state = instruction->state_before();
2287   ValueStack* prev_state = NULL;
2288   int scope_count = 0;
2289 
2290   assert(cur_state != NULL, "state_before must be set");
2291   do {
2292     int cur_bci = cur_state->bci();
2293     assert(cur_scope_data->scope() == cur_state->scope(), "scopes do not match");
2294     assert(cur_bci == SynchronizationEntryBCI || cur_bci == cur_scope_data->stream()->cur_bci(), "invalid bci");
2295 
2296     // join with all potential exception handlers
2297     XHandlers* list = cur_scope_data->xhandlers();
2298     const int n = list->length();
2299     for (int i = 0; i < n; i++) {


2350         XHandler* new_xhandler = new XHandler(h);
2351         new_xhandler->set_phi_operand(phi_operand);
2352         new_xhandler->set_scope_count(scope_count);
2353         exception_handlers->append(new_xhandler);
2354 
2355         // fill in exception handler subgraph lazily
2356         assert(!entry->is_set(BlockBegin::was_visited_flag), "entry must not be visited yet");
2357         cur_scope_data->add_to_work_list(entry);
2358 
2359         // stop when reaching catchall
2360         if (h->catch_type() == 0) {
2361           return exception_handlers;
2362         }
2363       }
2364     }
2365 
2366     if (exception_handlers->length() == 0) {
2367       // This scope and all callees do not handle exceptions, so the local
2368       // variables of this scope are not needed. However, the scope itself is
2369       // required for a correct exception stack trace -> clear out the locals.
2370       if (_compilation->env()->should_retain_local_variables()) {
2371         cur_state = cur_state->copy(ValueStack::ExceptionState, cur_state->bci());
2372       } else {
2373         cur_state = cur_state->copy(ValueStack::EmptyExceptionState, cur_state->bci());
2374       }
2375       if (prev_state != NULL) {
2376         prev_state->set_caller_state(cur_state);
2377       }
2378       if (instruction->exception_state() == NULL) {
2379         instruction->set_exception_state(cur_state);
2380       }
2381     }
2382 
2383     // Set up iteration for next time.
2384     // If parsing a jsr, do not grab exception handlers from the
2385     // parent scopes for this method (already got them, and they
2386     // needed to be cloned)
2387 
2388     while (cur_scope_data->parsing_jsr()) {
2389       cur_scope_data = cur_scope_data->parent();
2390     }


3234 ValueStack* GraphBuilder::copy_state_exhandling() {
3235   return copy_state_exhandling_with_bci(bci());
3236 }
3237 
3238 ValueStack* GraphBuilder::copy_state_for_exception() {
3239   return copy_state_for_exception_with_bci(bci());
3240 }
3241 
3242 ValueStack* GraphBuilder::copy_state_before_with_bci(int bci) {
3243   return state()->copy(ValueStack::StateBefore, bci);
3244 }
3245 
3246 ValueStack* GraphBuilder::copy_state_exhandling_with_bci(int bci) {
3247   if (!has_handler()) return NULL;
3248   return state()->copy(ValueStack::StateBefore, bci);
3249 }
3250 
3251 ValueStack* GraphBuilder::copy_state_for_exception_with_bci(int bci) {
3252   ValueStack* s = copy_state_exhandling_with_bci(bci);
3253   if (s == NULL) {
3254     if (_compilation->env()->should_retain_local_variables()) {
3255       s = state()->copy(ValueStack::ExceptionState, bci);
3256     } else {
3257       s = state()->copy(ValueStack::EmptyExceptionState, bci);
3258     }
3259   }
3260   return s;
3261 }
3262 
3263 int GraphBuilder::recursive_inline_level(ciMethod* cur_callee) const {
3264   int recur_level = 0;
3265   for (IRScope* s = scope(); s != NULL; s = s->caller()) {
3266     if (s->method() == cur_callee) {
3267       ++recur_level;
3268     }
3269   }
3270   return recur_level;
3271 }
3272 
3273 
3274 bool GraphBuilder::try_inline(ciMethod* callee, bool holder_known, Bytecodes::Code bc, Value receiver) {