/vm/src/any/fast_compiler/fcompiler.cpp

http://github.com/ticking/self · C++ · 250 lines · 175 code · 53 blank · 22 comment · 25 complexity · 22d626ec75d3c4c72afc491b88fb424e MD5 · raw file

  1. /* Sun-$Revision: 30.10 $ */
  2. /* Copyright 1992-2006 Sun Microsystems, Inc. and Stanford University.
  3. See the LICENSE file for license information. */
  4. # pragma implementation "fcompiler.hh"
  5. # include "_fcompiler.cpp.incl"
  6. # ifdef FAST_COMPILER
  7. FCompiler* theCompiler = NULL;
  8. int32 FCompiler::verifiedOffset() { return codeGen->verifiedOffset; }
  9. int32 FCompiler::diCheckOffset() { return codeGen->diCheckOffset; }
  10. int32 FCompiler::frameCreationOffset() { return codeGen->frameCreationOffset;}
  11. int32 FCompiler::frameSize() { return codeGen->frameSize; }
  12. ScopeDescRecorder* FCompiler::scopeDescRecorder() {return codeGen->scopeDescs;}
  13. Assembler* FCompiler::instructions() { return &codeGen->a; }
  14. FCompiler::FCompiler(compilingLookup* k, sendDesc* sd, nmln* d)
  15. : AbstractCompiler(k, sd, d) {
  16. if (VMNICProfiling) OS::profile(true);
  17. initialize();
  18. }
  19. void FCompiler::finalize() {
  20. theCompiler = NULL;
  21. theCodeGen = NULL;
  22. theAssembler = NULL;
  23. AbstractCompiler::finalize();
  24. if (VMNICProfiling) OS::profile(false);
  25. }
  26. void FCompiler::initialize() {
  27. assert(theCompiler == NULL,
  28. "shouldn't have but one fast compiler at a time");
  29. theCompiler = this;
  30. generateDebugCode = false;
  31. stackLocCount = extraArgCount = 0;
  32. countID = 0;
  33. codeGen = new CodeGen(L, send_desc, diLink);
  34. if (baseLookupType(L->lookupType()) == NormalBaseLookupType) {
  35. // ignore the receiver static bit (same nmethod covers both cases)
  36. L->clearReceiverStatic();
  37. }
  38. containsLoop = false;
  39. isImpure= false; // set to true when something is inlined
  40. }
  41. nmethod* FCompiler::compile() {
  42. EventMarker em("NIC-compiling %#lx %#lx", L->selector(), NULL);
  43. ElapsedTimer t(PrintCompilation || PrintCompilationStatistics);
  44. ShowCompileInMonitor sc(L->selector(), "NIC", false);
  45. // don't do any inlining when converting / single-stepping
  46. FlagSetting noinl(NICInlineDataAccess,
  47. NICInlineDataAccess && !generateDebugCode);
  48. dispatchToCode();
  49. codeGen->scopeDescs->generate();
  50. if (PrintCompilationStatistics) t.stop(); // don't include nmethod alloc
  51. nmethod* nm = new_nmethod(this, generateDebugCode);
  52. assert(theAssembler->verifyLabels(), "undefined labels");
  53. em.event.args[1] = nm;
  54. if (PrintCompilation || PrintCompilationStatistics) {
  55. float dt = IntervalTimer::dont_use_any_timer ? 0.0 : t.millisecs();
  56. if (PrintCompilation) {
  57. char buf[1000];
  58. sprintf(buf, "%#lx (%3.1f ms%s)\n", (long unsigned int)nm, dt,
  59. dt >= MaxCompilePause ? "!" : "");
  60. lprintf("%s", buf);
  61. }
  62. if (PrintCompilationStatistics) {
  63. lprintf("\n*NIC-time=|%2.1f| ms; to/co/sc/lo/de/bc= |%d|%d|%d|%d|%d|%d|",
  64. *(void**)&dt,
  65. (void*)(nm->instsLen() + nm->scopes->length() +
  66. nm->locsLen() + nm->depsLen),
  67. (void*)nm->instsLen(),
  68. (void*)nm->scopes->length(),
  69. (void*)nm->locsLen(),
  70. (void*)nm->depsLen,
  71. (void*) (nm->isAccess()
  72. ? 0 :
  73. ((methodMap*)(nm->method()->map()))
  74. ->codes()->length()));
  75. }
  76. }
  77. if (VerifyZoneOften) nm->verify();
  78. return nm;
  79. }
  80. void FCompiler::trace_compile(char *s) {
  81. if (PrintCompilation) {
  82. lprintf("*NIC-compiling %s method for %s:\n",
  83. s, sprintName(NULL, L->selector()));
  84. }
  85. }
  86. void FCompiler::assignmentCode() {
  87. trace_compile("assignment");
  88. realSlotRef *res= L->result()->as_real();
  89. lookupTarget* h = res->holder;
  90. slotDesc* dataSlot = h->map()->find_slot(res->desc->name);
  91. realSlotRef* dataRef = new realSlotRef(h, dataSlot);
  92. codeGen->assignmentCode(dataRef);
  93. MethodLookupKey* k= new_MethodLookupKey(L->key);
  94. ScopeInfo scope = codeGen->scopeDescs->
  95. addDataAssignmentScope( k,
  96. new LocationName(LReceiverReg),
  97. L->receiverMapOop(),
  98. methodHolder_or_map());
  99. codeGen->scopeDescs->addSlot(scope, 0, new LocationName(ArgLocation(0)));
  100. }
  101. void FCompiler::dataCode() {
  102. trace_compile("access");
  103. codeGen->prologue(true, 0);
  104. codeGen->lookup(Temp1, L->result()->as_real(), LReceiverReg);
  105. codeGen->epilogue(Temp1);
  106. MethodLookupKey* k= new_MethodLookupKey(L->key);
  107. (void) codeGen->scopeDescs->
  108. addDataAccessScope(k,
  109. new LocationName(LReceiverReg),
  110. L->receiverMapOop(),
  111. methodHolder_or_map());
  112. }
  113. void FCompiler::constantCode() {
  114. trace_compile("constant");
  115. codeGen->prologue(true, 0);
  116. codeGen->loadOop(Temp1, L->result()->as_real()->desc->data);
  117. codeGen->epilogue(Temp1);
  118. MethodLookupKey* k= new_MethodLookupKey(L->key);
  119. (void) codeGen->scopeDescs->
  120. addDataAccessScope(k,
  121. new LocationName(LReceiverReg),
  122. L->receiverMapOop(),
  123. methodHolder_or_map());
  124. }
  125. void FCompiler::methodCode() {
  126. trace_compile("normal");
  127. if (PrintNICSource && method() && method()->source() != NULL && method()->source()->copy_null_terminated()) {
  128. lprintf( "NIC source: ");
  129. method()->source()->string_print();
  130. lprintf( "\n");
  131. }
  132. codeGen->haveStackFrame = true;
  133. oop slotContents= L->result()->contents();
  134. MethodKind kind= slotContents->kind();
  135. containsLoop= ((methodMap*)slotContents->map())->containsLoop();
  136. countID = Memory->code->nextNMethodID();
  137. MethodLookupKey* k= new_MethodLookupKey(L->key);
  138. FSelfScope* s;
  139. switch (kind) {
  140. case OuterMethodType:
  141. s = new FMethodScope(debugging, k, method(), methodHolder_or_map());
  142. break;
  143. case BlockMethodType: {
  144. FScope* parentScope = NULL;
  145. assert(ReuseNICMethods || L->receiverMap()->is_block(),
  146. "was expecting block");
  147. blockOop block = (blockOop) L->receiver;
  148. assert_block(block, "expecting a block literal");
  149. frame* parentBS = block->scope(true);
  150. if (parentBS) {
  151. // caution: parentFrame could be on conversion stack, so use
  152. // sending frame as a starting point
  153. //
  154. // I see that sendingVFrame can also be on conversion stack,
  155. // so forget the frame hint -- dmu 1/96
  156. // Just to explain a bit more:
  157. // for the conversion, the frames being converted are
  158. // copied off the stack, and the sender is also copied.
  159. // So, starting with the sender is wrong, since it is not
  160. // on the stack, you cannot walk up the stack from it.
  161. // Also, the compiler wants the NEW frames anyway, so this
  162. // "hint" is just plain bogus. -- dmu
  163. // Guess what? Urs is here and he agrees! -- dmu 8/96
  164. // frame* sender =
  165. // L->sendingVFrame
  166. // ? L->sendingVFrame->fr
  167. // : currentProcess->last_self_frame(false);
  168. parentVFrame = block->parentVFrame(NULL, true)->as_compiled();
  169. if (parentVFrame) parentScope = new_FVFrameScope(debugging, parentVFrame);
  170. }
  171. if (parentScope) {
  172. s = new FBlockScope(debugging, k, method(), parentScope);
  173. } else {
  174. s = new FDeadBlockScope(debugging, k, method());
  175. }
  176. break;
  177. }
  178. default:
  179. ShouldNotReachHere();
  180. }
  181. needRegWindowFlushes = false;
  182. s->genCode();
  183. }
  184. fint FCompiler::incoming_arg_count() {
  185. return codeGen->incoming_arg_count();
  186. }
  187. void FCompiler::print() {
  188. print_short(); lprintf(":");
  189. L->print();
  190. L->result()->print();
  191. lprintf("\treceiver: ");
  192. L->receiver->print_real_oop();
  193. lprintf("\tcodeGen: %#lx\n", codeGen);
  194. }
  195. void FCompiler::print_short() {
  196. lprintf("fcompiler %#lx", (unsigned long)this); }
  197. # endif // FAST_COMPILER