Remove prefetch during mark

Wilkinson, Hugh hugh.wilkinson at intel.com
Thu Mar 1 21:47:36 UTC 2018


//Pseudo code for previous post regarding a construct for software prefetching.



{

  ZMarkStackEntry entry;

  uintptr_t addr;

  ZPage* page;

  bool inc_live;



  do {

    // 3rd pipeline stage executes within the outer loop.

    int x_mark = 0;

    do {

      // 2nd pipeline stage executes within the middle loop.

      int x_get = 0;

      do {

        // 1st pipeline stage executes within the inner loop.

        // First pipeline stage.



        // get_entry() is a merging of pop() and try_steal()

        if (UNLIKELY(!get_entry(entry))) {

          if (!fifo0_empty()) goto drain_fifo0;

          if (!fifo1_empty()) goto drain_fifo1;

          goto all_done;

        }

        else {

          if (UNLIKELY(entry.partial_array())) {

            follow_partial_array();

            continue;

          }

          addr = entry.object_address(entry);

          page = _pagetable->get(addr);

          // 1st stage prefetches ZLiveMap (within ZPage) and ZBitMap fields

          page->mark_object_prefetch(addr);

          store_context_fifo0(entry, addr, page);

          // Maximum of 2 iterations and typically 1 iteration.

          if (UNLIKELY(!fifo0_full()))

            if (x_get++ == 0)

              continue;

        }

        break;

      } while (UNLIKELY(true));



      // Second pipeline stage.

    drain_fifo0:

      retore_context_fifo0(entry, addr, page);

      if (UNLIKELY(page->is_allocating())) {

        continue;

      }

      inc_live = false;

      const bool success =

        page->mark_object(addr, entry.finalizable(), inc_live);

      if (!success) continue;  // no updates to bitmap

      // Second stage prefetches object

      uint8_t* p = (uint8_t *)addr;

      Prefetch::read((void*)&p[0],1);

      Prefetch::read((void*)&p[DEFAULT_CACHE_LINE_SIZE],1);

      store_context_fifo1(entry, addr, page, inc_live);

      // Maximum of 2 iterations and typically 1 iteration.

      if (UNLIKELY(!fifo0_full()))

        if (x_mark++ == 0)

          continue;

      break;

    } while (UNLIKELY(true));

    // Third pipeline stage.

  drain_fifo1:

    retore_context_fifo1(entry, addr, page, inc_live);

    if (LIKELY(inc_live)) {

      size_t size = ZUtils::object_size(addr);

      size_t aligned_size = align_up(size, page->object_alignment());

      cache->inc_live(page, aligned_size);

    }

    if (UNLIKELY(is_array(addr))) {

      follow_array_object();

    }

    else {

      follow_object();

    }

  } while (true);

 all_done:

}




More information about the zgc-dev mailing list