6951784: Zero deoptimizer changes

Wed, 12 May 2010 03:49:52 -0700

author
twisti
date
Wed, 12 May 2010 03:49:52 -0700
changeset 1869
22af4ce8dba1
parent 1868
df736661d0c8
child 1870
ef1a1d051971

6951784: Zero deoptimizer changes
Summary: The way Zero currently handles deoptimization can lead to methods being freed while they are still being executed.
Reviewed-by: twisti
Contributed-by: Gary Benson <gbenson@redhat.com>

src/cpu/zero/vm/cppInterpreter_zero.cpp file | annotate | diff | comparison | revisions
src/cpu/zero/vm/cppInterpreter_zero.hpp file | annotate | diff | comparison | revisions
src/cpu/zero/vm/entry_zero.hpp file | annotate | diff | comparison | revisions
     1.1 --- a/src/cpu/zero/vm/cppInterpreter_zero.cpp	Tue May 11 15:19:19 2010 -0700
     1.2 +++ b/src/cpu/zero/vm/cppInterpreter_zero.cpp	Wed May 12 03:49:52 2010 -0700
     1.3 @@ -37,15 +37,18 @@
     1.4    thread->reset_last_Java_frame();              \
     1.5    fixup_after_potential_safepoint()
     1.6  
     1.7 -void CppInterpreter::normal_entry(methodOop method, intptr_t UNUSED, TRAPS) {
     1.8 +int CppInterpreter::normal_entry(methodOop method, intptr_t UNUSED, TRAPS) {
     1.9    JavaThread *thread = (JavaThread *) THREAD;
    1.10  
    1.11    // Allocate and initialize our frame.
    1.12 -  InterpreterFrame *frame = InterpreterFrame::build(method, CHECK);
    1.13 +  InterpreterFrame *frame = InterpreterFrame::build(method, CHECK_0);
    1.14    thread->push_zero_frame(frame);
    1.15  
    1.16    // Execute those bytecodes!
    1.17    main_loop(0, THREAD);
    1.18 +
    1.19 +  // No deoptimized frames on the stack
    1.20 +  return 0;
    1.21  }
    1.22  
    1.23  void CppInterpreter::main_loop(int recurse, TRAPS) {
    1.24 @@ -165,7 +168,7 @@
    1.25      stack->push(result[-i]);
    1.26  }
    1.27  
    1.28 -void CppInterpreter::native_entry(methodOop method, intptr_t UNUSED, TRAPS) {
    1.29 +int CppInterpreter::native_entry(methodOop method, intptr_t UNUSED, TRAPS) {
    1.30    // Make sure method is native and not abstract
    1.31    assert(method->is_native() && !method->is_abstract(), "should be");
    1.32  
    1.33 @@ -173,7 +176,7 @@
    1.34    ZeroStack *stack = thread->zero_stack();
    1.35  
    1.36    // Allocate and initialize our frame
    1.37 -  InterpreterFrame *frame = InterpreterFrame::build(method, CHECK);
    1.38 +  InterpreterFrame *frame = InterpreterFrame::build(method, CHECK_0);
    1.39    thread->push_zero_frame(frame);
    1.40    interpreterState istate = frame->interpreter_state();
    1.41    intptr_t *locals = istate->locals();
    1.42 @@ -430,25 +433,26 @@
    1.43        ShouldNotReachHere();
    1.44      }
    1.45    }
    1.46 +
    1.47 +  // No deoptimized frames on the stack
    1.48 +  return 0;
    1.49  }
    1.50  
    1.51 -void CppInterpreter::accessor_entry(methodOop method, intptr_t UNUSED, TRAPS) {
    1.52 +int CppInterpreter::accessor_entry(methodOop method, intptr_t UNUSED, TRAPS) {
    1.53    JavaThread *thread = (JavaThread *) THREAD;
    1.54    ZeroStack *stack = thread->zero_stack();
    1.55    intptr_t *locals = stack->sp();
    1.56  
    1.57    // Drop into the slow path if we need a safepoint check
    1.58    if (SafepointSynchronize::do_call_back()) {
    1.59 -    normal_entry(method, 0, THREAD);
    1.60 -    return;
    1.61 +    return normal_entry(method, 0, THREAD);
    1.62    }
    1.63  
    1.64    // Load the object pointer and drop into the slow path
    1.65    // if we have a NullPointerException
    1.66    oop object = LOCALS_OBJECT(0);
    1.67    if (object == NULL) {
    1.68 -    normal_entry(method, 0, THREAD);
    1.69 -    return;
    1.70 +    return normal_entry(method, 0, THREAD);
    1.71    }
    1.72  
    1.73    // Read the field index from the bytecode, which looks like this:
    1.74 @@ -470,15 +474,14 @@
    1.75    constantPoolCacheOop cache = method->constants()->cache();
    1.76    ConstantPoolCacheEntry* entry = cache->entry_at(index);
    1.77    if (!entry->is_resolved(Bytecodes::_getfield)) {
    1.78 -    normal_entry(method, 0, THREAD);
    1.79 -    return;
    1.80 +    return normal_entry(method, 0, THREAD);
    1.81    }
    1.82  
    1.83    // Get the result and push it onto the stack
    1.84    switch (entry->flag_state()) {
    1.85    case ltos:
    1.86    case dtos:
    1.87 -    stack->overflow_check(1, CHECK);
    1.88 +    stack->overflow_check(1, CHECK_0);
    1.89      stack->alloc(wordSize);
    1.90      break;
    1.91    }
    1.92 @@ -558,20 +561,25 @@
    1.93        ShouldNotReachHere();
    1.94      }
    1.95    }
    1.96 +
    1.97 +  // No deoptimized frames on the stack
    1.98 +  return 0;
    1.99  }
   1.100  
   1.101 -void CppInterpreter::empty_entry(methodOop method, intptr_t UNUSED, TRAPS) {
   1.102 +int CppInterpreter::empty_entry(methodOop method, intptr_t UNUSED, TRAPS) {
   1.103    JavaThread *thread = (JavaThread *) THREAD;
   1.104    ZeroStack *stack = thread->zero_stack();
   1.105  
   1.106    // Drop into the slow path if we need a safepoint check
   1.107    if (SafepointSynchronize::do_call_back()) {
   1.108 -    normal_entry(method, 0, THREAD);
   1.109 -    return;
   1.110 +    return normal_entry(method, 0, THREAD);
   1.111    }
   1.112  
   1.113    // Pop our parameters
   1.114    stack->set_sp(stack->sp() + method->size_of_parameters());
   1.115 +
   1.116 +  // No deoptimized frames on the stack
   1.117 +  return 0;
   1.118  }
   1.119  
   1.120  InterpreterFrame *InterpreterFrame::build(const methodOop method, TRAPS) {
     2.1 --- a/src/cpu/zero/vm/cppInterpreter_zero.hpp	Tue May 11 15:19:19 2010 -0700
     2.2 +++ b/src/cpu/zero/vm/cppInterpreter_zero.hpp	Wed May 12 03:49:52 2010 -0700
     2.3 @@ -29,10 +29,10 @@
     2.4  
     2.5   public:
     2.6    // Method entries
     2.7 -  static void normal_entry(methodOop method, intptr_t UNUSED, TRAPS);
     2.8 -  static void native_entry(methodOop method, intptr_t UNUSED, TRAPS);
     2.9 -  static void accessor_entry(methodOop method, intptr_t UNUSED, TRAPS);
    2.10 -  static void empty_entry(methodOop method, intptr_t UNUSED, TRAPS);
    2.11 +  static int normal_entry(methodOop method, intptr_t UNUSED, TRAPS);
    2.12 +  static int native_entry(methodOop method, intptr_t UNUSED, TRAPS);
    2.13 +  static int accessor_entry(methodOop method, intptr_t UNUSED, TRAPS);
    2.14 +  static int empty_entry(methodOop method, intptr_t UNUSED, TRAPS);
    2.15  
    2.16   public:
    2.17    // Main loop of normal_entry
     3.1 --- a/src/cpu/zero/vm/entry_zero.hpp	Tue May 11 15:19:19 2010 -0700
     3.2 +++ b/src/cpu/zero/vm/entry_zero.hpp	Wed May 12 03:49:52 2010 -0700
     3.3 @@ -1,6 +1,6 @@
     3.4  /*
     3.5   * Copyright 2003-2007 Sun Microsystems, Inc.  All Rights Reserved.
     3.6 - * Copyright 2008, 2009 Red Hat, Inc.
     3.7 + * Copyright 2008, 2009, 2010 Red Hat, Inc.
     3.8   * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
     3.9   *
    3.10   * This code is free software; you can redistribute it and/or modify it
    3.11 @@ -41,20 +41,30 @@
    3.12    }
    3.13  
    3.14   private:
    3.15 -  typedef void (*NormalEntryFunc)(methodOop method,
    3.16 -                                  intptr_t  base_pc,
    3.17 -                                  TRAPS);
    3.18 -  typedef void (*OSREntryFunc)(methodOop method,
    3.19 -                               address   osr_buf,
    3.20 -                               intptr_t  base_pc,
    3.21 -                               TRAPS);
    3.22 +  typedef int (*NormalEntryFunc)(methodOop method,
    3.23 +                                 intptr_t  base_pc,
    3.24 +                                 TRAPS);
    3.25 +  typedef int (*OSREntryFunc)(methodOop method,
    3.26 +                              address   osr_buf,
    3.27 +                              intptr_t  base_pc,
    3.28 +                              TRAPS);
    3.29  
    3.30   public:
    3.31    void invoke(methodOop method, TRAPS) const {
    3.32 -    ((NormalEntryFunc) entry_point())(method, (intptr_t) this, THREAD);
    3.33 +    maybe_deoptimize(
    3.34 +      ((NormalEntryFunc) entry_point())(method, (intptr_t) this, THREAD),
    3.35 +      THREAD);
    3.36    }
    3.37    void invoke_osr(methodOop method, address osr_buf, TRAPS) const {
    3.38 -    ((OSREntryFunc) entry_point())(method, osr_buf, (intptr_t) this, THREAD);
    3.39 +    maybe_deoptimize(
    3.40 +      ((OSREntryFunc) entry_point())(method, osr_buf, (intptr_t) this, THREAD),
    3.41 +      THREAD);
    3.42 +  }
    3.43 +
    3.44 + private:
    3.45 +  static void maybe_deoptimize(int deoptimized_frames, TRAPS) {
    3.46 +    if (deoptimized_frames)
    3.47 +      CppInterpreter::main_loop(deoptimized_frames - 1, THREAD);
    3.48    }
    3.49  
    3.50   public:

mercurial