objArray_prims.cpp

Go to the documentation of this file.
00001 /* Copyright 1994, 1995 LongView Technologies L.L.C. $Revision: 1.15 $ */
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 # include "incls/_precompiled.incl"
00025 # include "incls/_objArray_prims.cpp.incl"
00026 
00027 TRACE_FUNC(TraceObjArrayPrims, "objArray")
00028 
00029 int objArrayPrimitives::number_of_calls;
00030 
00031 #define ASSERT_RECEIVER assert(receiver->is_objArray(), "receiver must be object array")
00032 
00033 PRIM_DECL_2(objArrayPrimitives::allocateSize, oop receiver, oop argument) {
00034   PROLOGUE_2("allocateSize", receiver, argument);
00035   assert(receiver->is_klass() && klassOop(receiver)->klass_part()->oop_is_objArray(),
00036          "receiver must object array class");
00037   if (!argument->is_smi())
00038     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00039 
00040   if (smiOop(argument)->value() < 0)
00041     return markSymbol(vmSymbols::negative_size());
00042 
00043   klassOop k        = klassOop(receiver);
00044   int      ni_size  = k->klass_part()->non_indexable_size();
00045   int      obj_size = ni_size + 1 + smiOop(argument)->value();
00046   // allocate
00047   objArrayOop obj = as_objArrayOop(Universe::allocate(obj_size, (memOop*)&k));
00048   // header
00049   memOop(obj)->initialize_header(k->klass_part()->has_untagged_contents(), k);
00050   // instance variables
00051   memOop(obj)->initialize_body(memOopDesc::header_size(), ni_size);
00052   // %optimized 'obj->set_length(size)'
00053   oop* base = (oop*) obj->addr();
00054   base[ni_size] = argument;
00055   memOop(obj)->initialize_body(ni_size+1, obj_size);
00056   return obj;
00057 }
00058 
00059 PRIM_DECL_1(objArrayPrimitives::size, oop receiver) {
00060   PROLOGUE_1("size", receiver);
00061   ASSERT_RECEIVER;
00062   // do the operation
00063   return as_smiOop(objArrayOop(receiver)->length());
00064 }
00065 
00066 PRIM_DECL_2(objArrayPrimitives::at, oop receiver, oop index) {
00067   PROLOGUE_2("at", receiver, index);
00068   ASSERT_RECEIVER;
00069 
00070   // check index type
00071   if (!index->is_smi())
00072     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00073 
00074   // check index value
00075   if (!objArrayOop(receiver)->is_within_bounds(smiOop(index)->value()))
00076      return markSymbol(vmSymbols::out_of_bounds());
00077 
00078   // do the operation
00079   return objArrayOop(receiver)->obj_at(smiOop(index)->value());
00080 }
00081 
00082 PRIM_DECL_3(objArrayPrimitives::atPut, oop receiver, oop index, oop value) {
00083   PROLOGUE_3("atPut", receiver, index, value);
00084   ASSERT_RECEIVER;
00085 
00086   // check index type
00087   if (!index->is_smi())
00088     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00089 
00090   // check index value
00091   if (!objArrayOop(receiver)->is_within_bounds(smiOop(index)->value()))
00092     return markSymbol(vmSymbols::out_of_bounds());
00093 
00094   // do the operation
00095   objArrayOop(receiver)->obj_at_put(smiOop(index)->value(), value);
00096   return receiver;
00097 }
00098 
00099 
00100 PRIM_DECL_2(objArrayPrimitives::at_all_put, oop receiver, oop obj) {
00101   PROLOGUE_2("at_all_put", receiver, obj);
00102   ASSERT_RECEIVER;
00103 
00104   int  length = objArrayOop(receiver)->length();
00105   if (obj->is_new() && receiver->is_old()) {
00106     // Do store checks
00107     for (int index = 1; index <= length; index++) {
00108       objArrayOop(receiver)->obj_at_put(index, obj); 
00109     }
00110   } else {
00111     // Ignore store check for speed
00112     set_oops(objArrayOop(receiver)->objs(1), length, obj);
00113   }
00114   return receiver;
00115 }
00116 
00117 PRIM_DECL_5(objArrayPrimitives::replace_from_to, oop receiver, oop from, oop to, oop source, oop start) {
00118   PROLOGUE_5("replace_from_to", receiver, from, to, source, start);
00119   ASSERT_RECEIVER;
00120 
00121   // check from type
00122   if (!from->is_smi())
00123     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00124 
00125   // check to type
00126   if (!to->is_smi())
00127     return markSymbol(vmSymbols::second_argument_has_wrong_type());
00128 
00129   // check source type
00130   if (!source->is_objArray())
00131     return markSymbol(vmSymbols::third_argument_has_wrong_type());
00132 
00133   // check start type
00134   if (!start->is_smi())
00135     return markSymbol(vmSymbols::third_argument_has_wrong_type());
00136 
00137   // check from > 0
00138   if (smiOop(from) <= 0)
00139     return markSymbol(vmSymbols::out_of_bounds());
00140 
00141   // check to < self size
00142   if (smiOop(to)->value() > objArrayOop(receiver)->length())
00143     return markSymbol(vmSymbols::out_of_bounds());
00144 
00145   // check from <= to
00146   if (smiOop(from)->value() > smiOop(to)->value())
00147     return markSymbol(vmSymbols::out_of_bounds());
00148 
00149   // check if source is big enough
00150   if (smiOop(start)->value() + (smiOop(to)->value() - smiOop(from)->value() + 1) > objArrayOop(source)->length())
00151     return markSymbol(vmSymbols::out_of_bounds());
00152 
00153   // Dispatch the operation to the array
00154   objArrayOop(receiver)->replace_from_to(smiOop(from)->value(), smiOop(to)->value(), objArrayOop(source), smiOop(start)->value());
00155 
00156   return receiver;
00157 }
00158 
00159 PRIM_DECL_4(objArrayPrimitives::copy_size, oop receiver, oop from, oop start, oop size) {
00160   PROLOGUE_4("copy_size", receiver, from, start, size);
00161   ASSERT_RECEIVER;
00162 
00163   // check from type
00164   if (!from->is_smi())
00165     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00166 
00167   // check start type
00168   if (!start->is_smi())
00169     return markSymbol(vmSymbols::second_argument_has_wrong_type());
00170 
00171   // check size type
00172   if (!size->is_smi())
00173     return markSymbol(vmSymbols::third_argument_has_wrong_type());
00174 
00175   // check from > 0
00176   if (smiOop(from) <= 0)
00177     return markSymbol(vmSymbols::out_of_bounds());
00178 
00179   // check start > 0
00180   if (smiOop(start) <= 0)
00181     return markSymbol(vmSymbols::out_of_bounds());
00182   
00183   // Check size is positive
00184   if (smiOop(size)->value() < 0)
00185     return markSymbol(vmSymbols::negative_size());
00186 
00187   HandleMark hm;
00188   Handle saved_receiver(receiver); 
00189 
00190   // allocation of object array
00191   klassOop k        = receiver->klass();
00192   int      ni_size  = k->klass_part()->non_indexable_size();
00193   int      obj_size = ni_size + 1 + smiOop(size)->value();
00194   // allocate
00195   objArrayOop obj = as_objArrayOop(Universe::allocate(obj_size, (memOop*)&k));
00196 
00197   objArrayOop src = saved_receiver.as_objArray();
00198 
00199   // header
00200   memOop(obj)->initialize_header(k->klass_part()->has_untagged_contents(), k);
00201   // copy instance variables
00202   for (int index = memOopDesc::header_size(); index < ni_size; index++ ) {
00203      obj->raw_at_put(index, src->raw_at(index));
00204   }
00205   // length
00206   obj->set_length(smiOop(size)->value());
00207   // fill the array
00208   obj->replace_and_fill(smiOop(from)->value(), smiOop(start)->value(), src);
00209 
00210   return obj;
00211 }

Generated on Mon Oct 9 13:37:18 2006 for Strongtalk VM by  doxygen 1.4.7