001    /*
002     *  This file is part of the Jikes RVM project (http://jikesrvm.org).
003     *
004     *  This file is licensed to You under the Eclipse Public License (EPL);
005     *  You may not use this file except in compliance with the License. You
006     *  may obtain a copy of the License at
007     *
008     *      http://www.opensource.org/licenses/eclipse-1.0.php
009     *
010     *  See the COPYRIGHT.txt file distributed with this work for information
011     *  regarding copyright ownership.
012     */
013    package org.jikesrvm.mm.mminterface;
014    
015    import org.jikesrvm.mm.mmtk.ScanThread;
016    import org.jikesrvm.scheduler.SystemThread;
017    import org.mmtk.plan.CollectorContext;
018    import org.vmmagic.pragma.BaselineNoRegisters;
019    import org.vmmagic.pragma.BaselineSaveLSRegisters;
020    import org.vmmagic.pragma.NoOptCompile;
021    import org.vmmagic.pragma.NonMoving;
022    import org.vmmagic.pragma.Uninterruptible;
023    import org.vmmagic.pragma.Unpreemptible;
024    
025    /**
026     * System thread used to perform garbage collection work.
027     */
028    @NonMoving
029    public final class CollectorThread extends SystemThread {
030    
031      /***********************************************************************
032       *
033       * Class variables
034       */
035    
036      /***********************************************************************
037       *
038       * Instance variables
039       */
040    
041      /** used by collector threads to hold state during stack scanning */
042      private final ScanThread threadScanner = new ScanThread();
043    
044      /** @return the thread scanner instance associated with this instance */
045      @Uninterruptible
046      public ScanThread getThreadScanner() { return threadScanner; }
047    
048      /***********************************************************************
049       *
050       * Initialization
051       */
052    
053      /**
054       * Constructor
055       *
056       * @param stack The stack this thread will run on
057       */
058      public CollectorThread(byte[] stack, CollectorContext context) {
059        super(stack, context.getClass().getName() + " [" + nextId + "]");
060        rvmThread.collectorContext = context;
061        rvmThread.collectorContext.initCollector(nextId);
062        nextId++;
063      }
064    
065      /** Next collector thread id. Collector threads are not created concurrently. */
066      private static int nextId = 0;
067    
068      /**
069       * Collection entry point. Delegates the real work to MMTk.
070       */
071      @Override
072      @NoOptCompile
073      // refs stored in registers by opt compiler will not be relocated by GC
074      @BaselineNoRegisters
075      // refs stored in registers by baseline compiler will not be relocated by GC, so use stack only
076      @BaselineSaveLSRegisters
077      // and store all registers from previous method in prologue, so that we can stack access them while scanning this thread.
078      @Unpreemptible
079      public void run() {
080        rvmThread.collectorContext.run();
081      }
082    }
083