00001 /* Copyright 1994, 1995 LongView Technologies L.L.C. $Revision: 1.17 $ */ 00002 /* Copyright (c) 2006, Sun Microsystems, Inc. 00003 All rights reserved. 00004 00005 Redistribution and use in source and binary forms, with or without modification, are permitted provided that the 00006 following conditions are met: 00007 00008 * Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 00009 * Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following 00010 disclaimer in the documentation and/or other materials provided with the distribution. 00011 * Neither the name of Sun Microsystems nor the names of its contributors may be used to endorse or promote products derived 00012 from this software without specific prior written permission. 00013 00014 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT 00015 NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL 00016 THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 00017 (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 00018 INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE 00019 OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE 00020 00021 00022 */ 00023 00024 00025 # include "incls/_precompiled.incl" 00026 # include "incls/_stackChunk.cpp.incl" 00027 00028 GrowableArray<const compiledVFrame*>* frames; 00029 GrowableArray<contextOop>* contexts; 00030 00031 bool StackChunkBuilder::_is_deoptimizing = false; 00032 int* StackChunkBuilder::frame_pointer = NULL; 00033 00034 StackChunkBuilder::StackChunkBuilder(int* fp, int size) { 00035 number_of_vframes = 0; 00036 number_of_locals = 0; 00037 array = new GrowableArray<oop>(size); 00038 frame_pointer = fp; 00039 } 00040 00041 StackChunkBuilder::~StackChunkBuilder() { 00042 } 00043 00044 void StackChunkBuilder::append(deltaVFrame* f) { 00045 number_of_vframes++; 00046 00047 // Append the frame information to the array 00048 methodOop method = f->method(); 00049 array->push(f->receiver()); 00050 array->push(f->method()); 00051 array->push(as_smiOop(f->bci())); 00052 00053 // push locals 00054 int number_of_temps = f->method()->number_of_stack_temporaries(); 00055 GrowableArray<oop>* stack = f->expression_stack(); 00056 00057 // push number of locals 00058 int locals = number_of_temps + stack->length(); 00059 array->push(as_smiOop(locals)); 00060 number_of_locals += locals; 00061 00062 // push context and temporaries 00063 // if a context is present store the canoniocal form as temporary 0. 00064 contextOop con = f->canonical_context(); 00065 if (con) { 00066 array->push(con); 00067 #ifdef ASSERT 00068 method->verify_context(con); 00069 #endif 00070 00071 // If we have pending nlrs (suspended in unwind protect) we have to update 00072 // the nlr targets if we match deoptimized frames 00073 if (!method->is_blockMethod()) { 00074 con->set_home_fp(frame_pointer); 00075 if (f->is_compiled_frame()) { 00076 Processes::update_nlr_targets((compiledVFrame*) f, con); 00077 } 00078 } 00079 } 00080 for (int index = con ? 1 : 0; index < number_of_temps; index++) 00081 array->push(f->temp_at(index)); 00082 00083 // push expression stack 00084 for (index = stack->length() - 1; index >= 0; index--) { 00085 array->push(stack->at(index)); 00086 } 00087 } 00088 00089 objArrayOop StackChunkBuilder::as_objArray() { 00090 int length = header_size() + array->length(); 00091 objArrayOop result = oopFactory::new_objArray(length); 00092 result->obj_at_put(1, as_smiOop(number_of_vframes)); 00093 result->obj_at_put(2, as_smiOop(number_of_locals)); 00094 for (int index = 0; index < array->length(); index++) 00095 result->obj_at_put(index + header_size() + 1, array->at(index)); 00096 return result; 00097 } 00098 00099 void StackChunkBuilder::context_at_put(const compiledVFrame* frame, contextOop con) { 00100 // Returns if no StackChunkBuilder is in use 00101 if (!is_deoptimizing()) { 00102 con->kill(); 00103 return; 00104 } 00105 00106 #ifdef ASSERT 00107 for (int index = 0; index < frames->length(); index++) { 00108 assert(!frames->at(index)->equal(frame), "should not be present"); 00109 } 00110 #endif 00111 con->set_home_fp(frame_pointer); 00112 frames->push(frame); 00113 contexts->push(con); 00114 } 00115 00116 contextOop StackChunkBuilder::context_at(const compiledVFrame* frame) { 00117 // Returns if no StackChunkBuilder is in use 00118 if (!is_deoptimizing()) return NULL; 00119 00120 // See if it's stored 00121 for (int index = 0; index < frames->length(); index++) { 00122 if (frames->at(index)->equal(frame)) { 00123 return contexts->at(index); 00124 } 00125 } 00126 return NULL; 00127 } 00128 00129 void StackChunkBuilder::begin_deoptimization() { 00130 assert(!is_deoptimizing(), "just checking"); 00131 _is_deoptimizing = true; 00132 frames = new GrowableArray<const compiledVFrame*>(100); 00133 contexts = new GrowableArray<contextOop>(100); 00134 } 00135 00136 void StackChunkBuilder::end_deoptimization() { 00137 assert(is_deoptimizing(), "just checking"); 00138 _is_deoptimizing = false; 00139 frames = NULL; 00140 contexts = NULL; 00141 00142 } 00143