system_prims.cpp

Go to the documentation of this file.
00001 /* Copyright 1994, 1995 LongView Technologies L.L.C. $Revision: 1.61 $ */
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/_system_prims.cpp.incl"
00027 
00028 TRACE_FUNC(TraceSystemPrims, "system")
00029 
00030 int systemPrimitives::number_of_calls;
00031 
00032 PRIM_DECL_5(systemPrimitives::createNamedInvocation, oop mixin, oop name, oop primary, oop superclass, oop format) {
00033   PROLOGUE_5("createNamedInvocation", mixin, primary, name, superclass, format)
00034 
00035   // Check argument types
00036   if (!mixin->is_mixin())
00037     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00038   if (!name->is_symbol())
00039     return markSymbol(vmSymbols::second_argument_has_wrong_type());
00040   if (!(primary == trueObj || primary == falseObj))
00041     return markSymbol(vmSymbols::third_argument_has_wrong_type());
00042   if (!superclass->is_klass())
00043     return markSymbol(vmSymbols::fourth_argument_has_wrong_type());
00044   if (!format->is_symbol())
00045     return markSymbol(vmSymbols::fifth_argument_has_wrong_type());
00046 
00047   Klass::Format f = Klass::format_from_symbol(symbolOop(format));
00048   if (f == Klass::no_klass) {
00049     return markSymbol(vmSymbols::argument_is_invalid());
00050   }
00051 
00052   BlockScavenge bs;
00053 
00054   // Create the new klass
00055   klassOop new_klass = klassOop(superclass)->klass_part()->create_subclass(mixinOop(mixin), f);
00056 
00057   if (new_klass == NULL) {
00058     // Create more detailed error message
00059     return markSymbol(vmSymbols::argument_is_invalid());
00060   }
00061 
00062   // Set the primary invocation if needed.
00063   if (primary == trueObj) {
00064     mixinOop(mixin)->set_primary_invocation(new_klass);
00065     mixinOop(mixin)->class_mixin()->set_primary_invocation(new_klass->klass());
00066     mixinOop(mixin)->set_installed(trueObj);
00067     mixinOop(mixin)->class_mixin()->set_installed(trueObj);
00068   }
00069 
00070   // Make sure mixin->classMixin is present
00071 
00072   // Add the global
00073   Universe::add_global(oopFactory::new_association(symbolOop(name), new_klass, true));
00074   return new_klass;
00075 }
00076 
00077 PRIM_DECL_3(systemPrimitives::createInvocation, oop mixin, oop superclass, oop format) {
00078   PROLOGUE_3("createInvocation", mixin, superclass, format)
00079 
00080   // Check argument types
00081   if (!mixin->is_mixin())
00082     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00083   if (!superclass->is_klass())
00084     return markSymbol(vmSymbols::second_argument_has_wrong_type());
00085   if (!format->is_symbol())
00086     return markSymbol(vmSymbols::third_argument_has_wrong_type());
00087 
00088   BlockScavenge bs;
00089 
00090   Klass::Format f = Klass::format_from_symbol(symbolOop(format));
00091   if (f == Klass::no_klass) {
00092     return markSymbol(vmSymbols::argument_is_invalid());
00093   }
00094 
00095   klassOop new_klass = klassOop(superclass)->klass_part()->create_subclass(mixinOop(mixin), f);
00096 
00097   if (new_klass == NULL) {
00098     // Create more detailed error message
00099     return markSymbol(vmSymbols::argument_is_invalid());
00100   }
00101 
00102   mixinOop(mixin)->set_installed(trueObj);
00103   mixinOop(mixin)->class_mixin()->set_installed(trueObj);
00104 
00105   return new_klass;
00106 }
00107 
00108 PRIM_DECL_1(systemPrimitives::applyChange, oop change) {
00109   PROLOGUE_1("applyChange", change)
00110   // Check argument types
00111   if (!change->is_objArray())
00112     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00113 
00114   BlockScavenge bs;
00115 
00116   return Reflection::apply_change(objArrayOop(change));
00117 }
00118 
00119 PRIM_DECL_1(systemPrimitives::scavenge, oop receiver) {
00120   PROLOGUE_1("scavenge", receiver)
00121   oop rec = receiver;
00122   VM_Scavenge op(&rec);
00123   // The operation takes place in the vmProcess
00124   VMProcess::execute(&op);
00125   return rec;
00126 }
00127 
00128 PRIM_DECL_1(systemPrimitives::garbageGollect, oop receiver) {
00129   PROLOGUE_1("garbageGollect", receiver);
00130   oop rec = receiver;
00131   VM_GarbageCollect op(&rec);
00132   // The operation takes place in the vmProcess
00133   VMProcess::execute(&op);
00134   return rec;
00135 }
00136 
00137 PRIM_DECL_0(systemPrimitives::breakpoint) {
00138   PROLOGUE_0("breakpoint")
00139   {
00140     ResourceMark rm;
00141     dispatchTable::intercept_for_step();
00142   }
00143   return trueObj;
00144 }
00145 
00146 PRIM_DECL_0(systemPrimitives::halt) {
00147   PROLOGUE_0("halt")
00148   __asm hlt
00149   return trueObj;
00150 }
00151 
00152 static oop fake_time() {
00153   static int time = 0;
00154   return oopFactory::new_double((double) time++);
00155 }
00156 
00157 PRIM_DECL_0(systemPrimitives::userTime) {
00158   PROLOGUE_0("userTime")
00159   if (UseTimers) { 
00160     os::updateTimes();
00161     return oopFactory::new_double(os::userTime());
00162   } else {
00163     return fake_time();
00164   }
00165 }
00166 
00167 PRIM_DECL_0(systemPrimitives::systemTime) {
00168   PROLOGUE_0("systemTime")
00169   if (UseTimers) { 
00170     os::updateTimes();
00171     return oopFactory::new_double(os::systemTime());
00172   } else {
00173     return fake_time();
00174   }
00175 }
00176 
00177 PRIM_DECL_0(systemPrimitives::elapsedTime) {
00178   PROLOGUE_0("elapsedTime")
00179   if (UseTimers) { 
00180     return oopFactory::new_double(os::elapsedTime());
00181   } else {
00182     return fake_time();
00183   }
00184 }
00185 
00186 PRIM_DECL_1(systemPrimitives::writeSnapshot, oop fileName) {
00187   PROLOGUE_1("writeSnapshot", fileName);
00188   SnapshotDesc sd;
00189   char* name = "fisk.snap";
00190   sd.write_on(name);
00191   if (sd.has_error()) return markSymbol(sd.error_symbol());
00192   return fileName;
00193 }
00194 
00195 PRIM_DECL_1(systemPrimitives::globalAssociationKey, oop receiver) {
00196   PROLOGUE_1("globalAssociationKey", receiver);
00197   assert(receiver->is_association(), "receiver must be association");
00198   return associationOop(receiver)->key();
00199 }
00200 
00201 PRIM_DECL_2(systemPrimitives::globalAssociationSetKey, oop receiver, oop key) {
00202   PROLOGUE_2("globalAssociationSetKey", receiver,  key);
00203   assert(receiver->is_association(), "receiver must be association");
00204   if (!key->is_symbol())
00205     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00206   associationOop(receiver)->set_key(symbolOop(key));
00207   return receiver;
00208 }
00209 
00210 PRIM_DECL_1(systemPrimitives::globalAssociationValue, oop receiver) {
00211   PROLOGUE_1("globalAssociationValue", receiver);
00212   assert(receiver->is_association(), "receiver must be association");
00213   return associationOop(receiver)->value();
00214 }
00215 
00216 PRIM_DECL_2(systemPrimitives::globalAssociationSetValue, oop receiver, oop value) {
00217   PROLOGUE_2("globalAssociationSetValue", receiver, value);
00218   assert(receiver->is_association(), "receiver must be association");
00219   associationOop(receiver)->set_value(value);
00220   return receiver;
00221 }
00222 
00223 PRIM_DECL_1(systemPrimitives::globalAssociationIsConstant, oop receiver) {
00224   PROLOGUE_1("globalAssociationIsConstant", receiver);
00225   assert(receiver->is_association(), "receiver must be association");
00226   return associationOop(receiver)->is_constant() ? trueObj : falseObj;
00227 }
00228 
00229 PRIM_DECL_2(systemPrimitives::globalAssociationSetConstant, oop receiver, oop value) {
00230   PROLOGUE_2("globalAssociationSetConstant", receiver, value);
00231   assert(receiver->is_association(), "receiver must be association");
00232   oop old_value = associationOop(receiver)->is_constant() ? trueObj : falseObj;
00233 
00234        if (value == trueObj)  associationOop(receiver)->set_is_constant(true);
00235   else if (value == falseObj) associationOop(receiver)->set_is_constant(false);
00236   else return markSymbol(vmSymbols::first_argument_has_wrong_type());
00237 
00238   return old_value;
00239 }
00240 
00241 PRIM_DECL_1(systemPrimitives::smalltalk_at, oop index) {
00242   PROLOGUE_1("smalltalk_at", index);
00243   if (!index->is_smi())
00244     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00245 
00246   if (!Universe::systemDictionaryObj()->is_within_bounds(smiOop(index)->value()))
00247      return markSymbol(vmSymbols::out_of_bounds());
00248 
00249   return Universe::systemDictionaryObj()->obj_at(smiOop(index)->value());
00250 }
00251 
00252 PRIM_DECL_2(systemPrimitives::smalltalk_at_put, oop key, oop value) {
00253   PROLOGUE_2("smalltalk_at_put", key, value);
00254 
00255   BlockScavenge bs;
00256   associationOop assoc = oopFactory::new_association(symbolOop(key), value, false);
00257   Universe::add_global(assoc);
00258   return assoc;
00259 }
00260 
00261 PRIM_DECL_1(systemPrimitives::smalltalk_remove_at, oop index) {
00262   PROLOGUE_1("smalltalk_remove_at", index);
00263 
00264   if (!index->is_smi())
00265     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00266 
00267   if (!Universe::systemDictionaryObj()->is_within_bounds(smiOop(index)->value()))
00268      return markSymbol(vmSymbols::out_of_bounds());
00269 
00270   BlockScavenge bs;
00271 
00272   associationOop assoc = associationOop(Universe::systemDictionaryObj()->obj_at(smiOop(index)->value()));
00273   Universe::remove_global_at(smiOop(index)->value());
00274   return assoc;
00275 }
00276 
00277 PRIM_DECL_0(systemPrimitives::smalltalk_size) {
00278   PROLOGUE_0("smalltalk_size");
00279   return as_smiOop(Universe::systemDictionaryObj()->length());
00280 }
00281 
00282 PRIM_DECL_0(systemPrimitives::smalltalk_array) {
00283   PROLOGUE_0("smalltalk_array");
00284   return Universe::systemDictionaryObj();
00285 }
00286 
00287 PRIM_DECL_0(systemPrimitives::quit) {
00288   PROLOGUE_0("quit");
00289   exit(0);
00290   return badOop;
00291 }
00292 
00293 PRIM_DECL_0(systemPrimitives::printPrimitiveTable) {
00294   PROLOGUE_0("printPrimitiveTable");
00295   primitives::print_table();
00296   return trueObj;
00297 }
00298 
00299 PRIM_DECL_0(systemPrimitives::print_memory) {
00300   PROLOGUE_0("print_memory");
00301   Universe::print();
00302   return trueObj;
00303 }
00304 
00305 PRIM_DECL_0(systemPrimitives::print_zone) {
00306   PROLOGUE_0("print_zone");
00307   Universe::code->print();
00308   return trueObj;
00309 }
00310 
00311 PRIM_DECL_1(systemPrimitives::defWindowProc, oop resultProxy) {
00312   PROLOGUE_1("defWindowProc", resultProxy);
00313   if (!resultProxy->is_proxy())
00314     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00315   std->print_cr("Please use the new Platform DLLLookup system to retrieve DefWindowProcA");
00316   dll_func func = DLLs::lookup(oopFactory::new_symbol("user"), oopFactory::new_symbol("DefWindowProcA"));
00317   proxyOop(resultProxy)->set_pointer(func);
00318   return resultProxy;
00319 }
00320 
00321 PRIM_DECL_1(systemPrimitives::windowsHInstance, oop resultProxy) {
00322   PROLOGUE_1("windowsHInstance", resultProxy);
00323   if (!resultProxy->is_proxy())
00324     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00325   proxyOop(resultProxy)->set_pointer(os::get_hInstance());
00326   return resultProxy;
00327 }
00328 
00329 PRIM_DECL_1(systemPrimitives::windowsHPrevInstance, oop resultProxy) {
00330   PROLOGUE_1("windowsHPrevInstance", resultProxy);
00331   if (!resultProxy->is_proxy())
00332     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00333   proxyOop(resultProxy)->set_pointer(os::get_prevInstance());
00334   return resultProxy;
00335 }
00336 
00337 PRIM_DECL_0(systemPrimitives::windowsNCmdShow) {
00338   PROLOGUE_0("windowsNCmdShow");
00339   return as_smiOop(os::get_nCmdShow());
00340 }
00341 
00342 PRIM_DECL_1(systemPrimitives::characterFor, oop value) {
00343   PROLOGUE_1("characterFor", value);
00344 
00345   // check value type
00346   if (!value->is_smi())
00347     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00348   
00349   if ((unsigned int) smiOop(value)->value() < 256)
00350     // return the n+1'th element in asciiCharacter
00351     return Universe::asciiCharacters()->obj_at(smiOop(value)->value() + 1);
00352   else return markSymbol(vmSymbols::out_of_bounds());
00353 }
00354 
00355 PRIM_DECL_0(systemPrimitives::traceStack) {
00356   PROLOGUE_0("traceStack");
00357   DeltaProcess::active()->trace_stack();
00358   return trueObj;
00359 }
00360 
00361 // Flat Profiler Primitives
00362 
00363 PRIM_DECL_0(systemPrimitives::flat_profiler_reset) {
00364   PROLOGUE_0("flat_profiler_reset");
00365   FlatProfiler::reset();
00366   return trueObj;
00367 }
00368 
00369 PRIM_DECL_0(systemPrimitives::flat_profiler_process) {
00370   PROLOGUE_0("flat_profiler_process");
00371   DeltaProcess* proc = FlatProfiler::process();
00372   return proc == NULL ? nilObj : proc->processObj();
00373 }
00374 
00375 PRIM_DECL_1(systemPrimitives::flat_profiler_engage, oop process) {
00376   PROLOGUE_1("flat_profiler_engage", process);
00377 
00378   // check value type
00379   if (!process->is_process())
00380     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00381 
00382   FlatProfiler::engage(processOop(process)->process());
00383   return process;
00384 }
00385 
00386 PRIM_DECL_0(systemPrimitives::flat_profiler_disengage) {
00387   PROLOGUE_0("flat_profiler_disengage");
00388   DeltaProcess* proc = FlatProfiler::disengage();
00389   return proc == NULL ? nilObj : proc->processObj();
00390 }
00391 
00392 PRIM_DECL_0(systemPrimitives::flat_profiler_print) {
00393   PROLOGUE_0("flat_profiler_print");
00394   FlatProfiler::print(0);
00395   return trueObj;
00396 }
00397 
00398 PRIM_DECL_0(systemPrimitives::notificationQueueGet) {
00399   PROLOGUE_0("notificationQueueGet");
00400   if (NotificationQueue::is_empty())
00401     return markSymbol(vmSymbols::empty_queue());
00402   return NotificationQueue::get();
00403 }
00404 
00405 
00406 PRIM_DECL_1(systemPrimitives::notificationQueuePut, oop value) {
00407   PROLOGUE_1("notificationQueuePut", value);
00408   NotificationQueue::put(value);
00409   return value;
00410 }
00411 
00412 PRIM_DECL_1(systemPrimitives::hadNearDeathExperience, oop value) {
00413   PROLOGUE_1("hadNearDeathExperience", value);
00414   return (value->is_mem() && memOop(value)->mark()->is_near_death()) 
00415          ? trueObj : falseObj;
00416 }
00417 
00418 
00419 PRIM_DECL_2(systemPrimitives::dll_setup, oop receiver, oop selector) {
00420   PROLOGUE_2("dll_setup", receiver, selector);
00421 
00422   if (!selector->is_symbol())
00423     return markSymbol(vmSymbols::second_argument_has_wrong_type());
00424 
00425   if (symbolOop(selector)->number_of_arguments() != 2)
00426     return markSymbol(vmSymbols::failed());
00427 
00428   Universe::set_dll_lookup(receiver, symbolOop(selector));
00429   return receiver;
00430 }
00431 
00432 PRIM_DECL_3(systemPrimitives::dll_lookup, oop name, oop library, oop result) {
00433   PROLOGUE_3("dll_lookup", name, library, result);
00434 
00435   if (!name->is_symbol())
00436     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00437 
00438   if (!library->is_proxy())
00439     return markSymbol(vmSymbols::second_argument_has_wrong_type());
00440 
00441   if (!result->is_proxy())
00442     return markSymbol(vmSymbols::third_argument_has_wrong_type());
00443 
00444   dll_func res = DLLs::lookup(symbolOop(name), (DLL*) proxyOop(library)->get_pointer());
00445   if (res) {
00446     proxyOop(result)->set_pointer(res);
00447     return result;
00448   } else {
00449     return markSymbol(vmSymbols::not_found());
00450   }
00451 }
00452 
00453 PRIM_DECL_2(systemPrimitives::dll_load, oop name, oop library) {
00454   PROLOGUE_2("dll_load", name, library);
00455 
00456   if (!name->is_symbol())
00457     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00458 
00459   if (!library->is_proxy())
00460     return markSymbol(vmSymbols::second_argument_has_wrong_type());
00461 
00462   DLL* res = DLLs::load(symbolOop(name));
00463   if (res) {
00464     proxyOop(library)->set_pointer(res);
00465     return library;
00466   } else {
00467     return markSymbol(vmSymbols::not_found());
00468   }
00469 }
00470 
00471 PRIM_DECL_1(systemPrimitives::dll_unload, oop library) {
00472   PROLOGUE_1("dll_unload", library);
00473 
00474   if (!library->is_proxy())
00475     return markSymbol(vmSymbols::second_argument_has_wrong_type());
00476 
00477   return DLLs::unload((DLL*) proxyOop(library)->get_pointer())
00478        ? library
00479        : markSymbol(vmSymbols::failed());
00480 }
00481 
00482 // Inlining Database
00483 
00484 PRIM_DECL_0(systemPrimitives::inlining_database_directory) {
00485   PROLOGUE_0("inlining_database_directory");
00486   return oopFactory::new_symbol(InliningDatabase::directory());
00487 }
00488 
00489 PRIM_DECL_1(systemPrimitives::inlining_database_set_directory, oop name) {
00490   PROLOGUE_1("inlining_database_set_directory", name);
00491 
00492   // Check type on argument
00493   if (!name->is_byteArray() && !name->is_doubleByteArray())
00494     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00495 
00496   ResourceMark rm;
00497 
00498   int len = name->is_byteArray() ? byteArrayOop(name)->length() : doubleByteArrayOop(name)->length();
00499   char* str = NEW_C_HEAP_ARRAY(char, len+1);
00500   name->is_byteArray()
00501   ?       byteArrayOop(name)->copy_null_terminated(str, len+1)
00502   : doubleByteArrayOop(name)->copy_null_terminated(str, len+1);
00503   // Potential memory leak, but this is temporary
00504   InliningDatabase::set_directory(str);
00505   return trueObj;
00506 }
00507 
00508 PRIM_DECL_1(systemPrimitives::inlining_database_file_out_class, oop receiver_class) {
00509   PROLOGUE_1("inlining_database_file_out_class", receiver_class);
00510 
00511   // Check type on argument
00512   if (!receiver_class->is_klass())
00513     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00514 
00515   // File out the class
00516   return as_smiOop(InliningDatabase::file_out(klassOop(receiver_class)));
00517 }
00518 
00519 PRIM_DECL_0(systemPrimitives::inlining_database_file_out_all) {
00520   PROLOGUE_0("inlining_database_file_out_all");
00521 
00522   // File out all nmethods
00523   return as_smiOop(InliningDatabase::file_out_all());
00524 }
00525 
00526 PRIM_DECL_1(systemPrimitives::inlining_database_compile, oop file_name) {
00527   PROLOGUE_1("inlining_database_compile", file_name);
00528 
00529   // Check type on argument
00530   if (!file_name->is_byteArray() && !file_name->is_doubleByteArray())
00531     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00532 
00533   ResourceMark rm;
00534 
00535   int len = file_name->is_byteArray() ? byteArrayOop(file_name)->length() : doubleByteArrayOop(file_name)->length();
00536   char* str = NEW_RESOURCE_ARRAY(char, len+1);
00537   file_name->is_byteArray()
00538   ?       byteArrayOop(file_name)->copy_null_terminated(str, len+1)
00539   : doubleByteArrayOop(file_name)->copy_null_terminated(str, len+1);
00540 
00541   RScope* rs = InliningDatabase::file_in(str);
00542   if (rs) {
00543     // Remove old nmethod if present
00544     nmethod* old_nm = Universe::code->lookup(rs->key());
00545     if (old_nm) {
00546       old_nm->makeZombie(false);
00547     }
00548 
00549     VM_OptimizeRScope op(rs);
00550     VMProcess::execute(&op);
00551 
00552     if (TraceInliningDatabase) {
00553       std->print_cr("compiling {%s} completed", str);
00554       std->print_cr("[Database]");
00555       rs->print_inlining_database_on(std, NULL, -1, 0);
00556       std->print_cr("[Compiled method]");
00557       op.result()->print_inlining_database_on(std);
00558     }
00559   } else {
00560     if (TraceInliningDatabase) {
00561        std->print_cr("compiling {%s} failed", str);
00562     }
00563   }
00564   return trueObj;
00565 }
00566 
00567 PRIM_DECL_0(systemPrimitives::inlining_database_compile_next) {
00568   PROLOGUE_0("inlining_database_compile_next");
00569   if (!UseInliningDatabase) {
00570     return falseObj;
00571   }
00572 
00573   bool end_of_table; 
00574   RScope* rs = InliningDatabase::select_and_remove(&end_of_table);
00575   if (rs) {
00576     VM_OptimizeRScope op(rs);
00577     VMProcess::execute(&op);
00578     if (TraceInliningDatabase) {
00579       std->print("Compiling ");
00580       op.result()->key.print_on(std);
00581       std->print_cr(" in background = 0x%lx", op.result());
00582     }
00583   }
00584   return end_of_table ? falseObj : trueObj;
00585 }
00586 
00587 PRIM_DECL_1(systemPrimitives::inlining_database_mangle, oop name) {
00588   PROLOGUE_1("inlining_database_mangle", name);
00589 
00590   // Check type on argument
00591   if (!name->is_byteArray() && !name->is_doubleByteArray())
00592     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00593 
00594   ResourceMark rm;
00595 
00596   int len = name->is_byteArray() ? byteArrayOop(name)->length() : doubleByteArrayOop(name)->length();
00597   char* str = NEW_RESOURCE_ARRAY(char, len+1);
00598   name->is_byteArray()
00599   ?       byteArrayOop(name)->copy_null_terminated(str, len+1)
00600   : doubleByteArrayOop(name)->copy_null_terminated(str, len+1);
00601   return oopFactory::new_byteArray(InliningDatabase::mangle_name(str));
00602 }
00603 
00604   
00605 PRIM_DECL_1(systemPrimitives::inlining_database_demangle, oop name) {
00606   PROLOGUE_1("inlining_database_demangle", name);
00607   // Check type on argument
00608   if (!name->is_byteArray() && !name->is_doubleByteArray())
00609     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00610 
00611   ResourceMark rm;
00612 
00613   int len = name->is_byteArray() ? byteArrayOop(name)->length() : doubleByteArrayOop(name)->length();
00614   char* str = NEW_RESOURCE_ARRAY(char, len+1);
00615   name->is_byteArray()
00616   ?       byteArrayOop(name)->copy_null_terminated(str, len+1)
00617   : doubleByteArrayOop(name)->copy_null_terminated(str, len+1);
00618   return oopFactory::new_byteArray(InliningDatabase::unmangle_name(str));
00619 }
00620 
00621 PRIM_DECL_2(systemPrimitives::inlining_database_add_entry, oop receiver_class, oop method_selector) {
00622   PROLOGUE_2("inlining_database_add_entry", receiver_class, method_selector);
00623 
00624   // Check type of argument
00625   if (!receiver_class->is_klass())
00626     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00627 
00628   // Check type of argument
00629   if (!method_selector->is_symbol())
00630     return markSymbol(vmSymbols::second_argument_has_wrong_type());
00631 
00632   LookupKey key(klassOop(receiver_class), method_selector);
00633   InliningDatabase::add_lookup_entry(&key);
00634   return receiver_class;
00635 }
00636 
00637 PRIM_DECL_0(systemPrimitives::sliding_system_average) {
00638   PROLOGUE_0("system_sliding_average");
00639 
00640   if (!UseSlidingSystemAverage) 
00641     return markSymbol(vmSymbols::not_active());
00642 
00643   unsigned int* array = SlidingSystemAverage::update();
00644 
00645   objArrayOop result = oopFactory::new_objArray(SlidingSystemAverage::number_of_cases-1);
00646 
00647   for (int index = 1; index < SlidingSystemAverage::number_of_cases; index++) {
00648     result->obj_at_put(index, as_smiOop(array[index]));
00649   }
00650   return result;
00651 }
00652 
00653 // Enumeration primitives
00654 // - it is important to exclude contextOops since they should be invisible to the Smalltalk level. 
00655 
00656 class InstancesOfClosure: public ObjectClosure {
00657  public:
00658   InstancesOfClosure(klassOop target, int limit) {
00659     this->result = new GrowableArray<oop>(100);
00660     this->target = target;
00661     this->limit  = limit;
00662   }
00663 
00664   int                 limit;
00665   klassOop            target;
00666   GrowableArray<oop>* result; 
00667  
00668   void do_object(memOop obj) {
00669     if (obj->klass() == target) {
00670       if (result->length() < limit && !obj->is_context()) {
00671         result->append(obj);
00672       }
00673     }
00674   }
00675 };
00676 
00677 PRIM_DECL_2(systemPrimitives::instances_of, oop klass, oop limit) {
00678   PROLOGUE_2("instances_of", klass, limit);
00679 
00680   // Check type of argument
00681   if (!klass->is_klass())
00682     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00683   if (!limit->is_smi())
00684     return markSymbol(vmSymbols::second_argument_has_wrong_type());
00685 
00686   BlockScavenge bs;
00687   ResourceMark rm;
00688 
00689   InstancesOfClosure blk(klassOop(klass), smiOop(limit)->value());
00690   Universe::object_iterate(&blk);
00691 
00692   int length = blk.result->length();
00693   objArrayOop result = oopFactory::new_objArray(length);
00694   for (int index = 1; index <= length; index++) {
00695     result->obj_at_put(index, blk.result->at(index-1));
00696   }
00697   return result;
00698 }
00699 
00700 class ConvertClosure : public OopClosure {
00701   void do_oop(oop* o) {
00702     Reflection::convert(o);
00703   }
00704 };
00705 
00706 class HasReferenceClosure : public OopClosure {
00707   oop target;
00708  public:
00709   HasReferenceClosure(oop target) {
00710     this->target = target;
00711     this->result = false;
00712   }  
00713   void do_oop(oop* o) {
00714     if (*o == target) result = true;
00715   }
00716   bool result;
00717 };
00718 
00719 class ReferencesToClosure: public ObjectClosure {
00720  public:
00721   ReferencesToClosure(oop target, int limit) {
00722     this->result = new GrowableArray<oop>(100);
00723     this->target = target;
00724     this->limit  = limit;
00725   }
00726 
00727   int                 limit;
00728   oop                 target;
00729   GrowableArray<oop>* result; 
00730  
00731   bool has_reference(memOop obj) {
00732     HasReferenceClosure blk(target);
00733     obj->oop_iterate(&blk);
00734     return blk.result;
00735   }
00736 
00737   void do_object(memOop obj) {
00738     if (has_reference(obj)) {
00739       if (result->length() < limit && !obj->is_context()) {
00740         result->append(obj);
00741       }
00742     }
00743   }
00744 };
00745 
00746 PRIM_DECL_2(systemPrimitives::references_to, oop obj, oop limit) {
00747   PROLOGUE_2("references_to", obj, limit);
00748 
00749   // Check type of argument
00750   if (!limit->is_smi())
00751     return markSymbol(vmSymbols::second_argument_has_wrong_type());
00752 
00753   BlockScavenge bs;
00754   ResourceMark rm;
00755 
00756   ReferencesToClosure blk(obj, smiOop(limit)->value());
00757   Universe::object_iterate(&blk);
00758 
00759   int length = blk.result->length();
00760   objArrayOop result = oopFactory::new_objArray(length);
00761   for (int index = 1; index <= length; index++) {
00762     result->obj_at_put(index, blk.result->at(index-1));
00763   }
00764   return result;
00765 }
00766 
00767 class HasInstanceReferenceClosure : public OopClosure {
00768   klassOop target;
00769  public:
00770   HasInstanceReferenceClosure(klassOop target) {
00771     this->target = target;
00772     this->result = false;
00773   }  
00774   void do_oop(oop* o) {
00775     if ((*o)->klass() == target) result = true;
00776   }
00777   bool result;
00778 };
00779 
00780 class ReferencesToInstancesOfClosure: public ObjectClosure {
00781  public:
00782   ReferencesToInstancesOfClosure(klassOop target, int limit) {
00783     this->result = new GrowableArray<oop>(100);
00784     this->target = target;
00785     this->limit  = limit;
00786   }
00787 
00788   int                 limit;
00789   klassOop            target;
00790   GrowableArray<oop>* result; 
00791  
00792   bool has_reference(memOop obj) {
00793     HasInstanceReferenceClosure blk(target);
00794     obj->oop_iterate(&blk);
00795     return blk.result;
00796   }
00797 
00798   void do_object(memOop obj) {
00799     if (has_reference(obj)) {
00800       if (result->length() < limit && !obj->is_context()) {
00801         result->append(obj);
00802       }
00803     }
00804   }
00805 };
00806 
00807 PRIM_DECL_2(systemPrimitives::references_to_instances_of, oop klass, oop limit) {
00808   PROLOGUE_2("references_to_instances_of", klass, limit);
00809 
00810   // Check type of argument
00811   if (!klass->is_klass())
00812     return markSymbol(vmSymbols::first_argument_has_wrong_type());
00813   if (!limit->is_smi())
00814     return markSymbol(vmSymbols::second_argument_has_wrong_type());
00815 
00816   BlockScavenge bs;
00817   ResourceMark rm;
00818 
00819   ReferencesToInstancesOfClosure blk(klassOop(klass), smiOop(limit)->value());
00820   Universe::object_iterate(&blk);
00821 
00822   int length = blk.result->length();
00823   objArrayOop result = oopFactory::new_objArray(length);
00824   for (int index = 1; index <= length; index++) {
00825     result->obj_at_put(index, blk.result->at(index-1));
00826   }
00827   return result;
00828 }
00829 
00830 class AllObjectsClosure: public ObjectClosure {
00831  public:
00832   AllObjectsClosure(int limit) {
00833     this->result = new GrowableArray<oop>(20000);
00834     this->limit  = limit;
00835   }
00836 
00837   int                 limit;
00838   GrowableArray<oop>* result; 
00839  
00840   void do_object(memOop obj) {
00841     if (result->length() < limit && !obj->is_context()) {
00842       result->append(obj);
00843     }
00844   }
00845 };
00846 
00847 PRIM_DECL_1(systemPrimitives::all_objects, oop limit) {
00848   PROLOGUE_1("all_objects", limit);
00849 
00850   // Check type of argument
00851   if (!limit->is_smi())
00852     return markSymbol(vmSymbols::second_argument_has_wrong_type());
00853 
00854   BlockScavenge bs;
00855   ResourceMark rm;
00856 
00857   AllObjectsClosure blk(smiOop(limit)->value());
00858   Universe::object_iterate(&blk);
00859 
00860   int length = blk.result->length();
00861   objArrayOop result = oopFactory::new_objArray(length);
00862   for (int index = 1; index <= length; index++) {
00863     result->obj_at_put(index, blk.result->at(index-1));
00864   }
00865   return result;
00866 }
00867 
00868 PRIM_DECL_0(systemPrimitives::flush_code_cache) {
00869   PROLOGUE_0("flush_code_cache");
00870   Universe::code->flush();
00871   return trueObj;
00872 }
00873 
00874 PRIM_DECL_0(systemPrimitives::flush_dead_code) {
00875   PROLOGUE_0("flush_dead_code");
00876   Universe::code->flushZombies();
00877   return trueObj;
00878 }

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