2012-12-22 02:15:33 +01:00
|
|
|
// Copyright 2012 The Go Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style
|
|
|
|
// license that can be found in the LICENSE file.
|
|
|
|
|
|
|
|
// Garbage collector (GC)
|
|
|
|
|
|
|
|
// GC instruction opcodes.
|
|
|
|
//
|
|
|
|
// The opcode of an instruction is followed by zero or more
|
|
|
|
// arguments to the instruction.
|
|
|
|
//
|
|
|
|
// Meaning of arguments:
|
|
|
|
// off Offset (in bytes) from the start of the current object
|
|
|
|
// objgc Pointer to GC info of an object
|
2013-07-16 08:54:42 +02:00
|
|
|
// objgcrel Offset to GC info of an object
|
2012-12-22 02:15:33 +01:00
|
|
|
// len Length of an array
|
|
|
|
// elemsize Size (in bytes) of an element
|
|
|
|
// size Size (in bytes)
|
2013-07-16 08:54:42 +02:00
|
|
|
//
|
|
|
|
// NOTE: There is a copy of these in ../reflect/type.go.
|
|
|
|
// They must be kept in sync.
|
2012-12-22 02:15:33 +01:00
|
|
|
enum {
|
|
|
|
GC_END, // End of object, loop or subroutine. Args: none
|
|
|
|
GC_PTR, // A typed pointer. Args: (off, objgc)
|
|
|
|
GC_APTR, // Pointer to an arbitrary object. Args: (off)
|
|
|
|
GC_ARRAY_START, // Start an array with a fixed length. Args: (off, len, elemsize)
|
|
|
|
GC_ARRAY_NEXT, // The next element of an array. Args: none
|
2013-07-16 08:54:42 +02:00
|
|
|
GC_CALL, // Call a subroutine. Args: (off, objgcrel)
|
|
|
|
GC_CHAN_PTR, // Go channel. Args: (off, ChanType*)
|
2012-12-22 02:15:33 +01:00
|
|
|
GC_STRING, // Go string. Args: (off)
|
|
|
|
GC_EFACE, // interface{}. Args: (off)
|
|
|
|
GC_IFACE, // interface{...}. Args: (off)
|
|
|
|
GC_SLICE, // Go slice. Args: (off, objgc)
|
|
|
|
GC_REGION, // A region/part of the current object. Args: (off, size, objgc)
|
|
|
|
|
|
|
|
GC_NUM_INSTR, // Number of instruction opcodes
|
|
|
|
};
|
|
|
|
|
|
|
|
enum {
|
|
|
|
// Size of GC's fixed stack.
|
|
|
|
//
|
|
|
|
// The current GC implementation permits:
|
|
|
|
// - at most 1 stack allocation because of GC_CALL
|
|
|
|
// - at most GC_STACK_CAPACITY allocations because of GC_ARRAY_START
|
|
|
|
GC_STACK_CAPACITY = 8,
|
|
|
|
};
|
2014-07-19 10:53:52 +02:00
|
|
|
|
|
|
|
enum {
|
|
|
|
ScanStackByFrames = 1,
|
|
|
|
IgnorePreciseGC = 0,
|
|
|
|
|
|
|
|
// Four bits per word (see #defines below).
|
|
|
|
wordsPerBitmapWord = sizeof(void*)*8/4,
|
|
|
|
bitShift = sizeof(void*)*8/4,
|
|
|
|
};
|
|
|
|
|
|
|
|
// Bits in per-word bitmap.
|
|
|
|
// #defines because enum might not be able to hold the values.
|
|
|
|
//
|
|
|
|
// Each word in the bitmap describes wordsPerBitmapWord words
|
|
|
|
// of heap memory. There are 4 bitmap bits dedicated to each heap word,
|
|
|
|
// so on a 64-bit system there is one bitmap word per 16 heap words.
|
|
|
|
// The bits in the word are packed together by type first, then by
|
|
|
|
// heap location, so each 64-bit bitmap word consists of, from top to bottom,
|
|
|
|
// the 16 bitMarked bits for the corresponding heap words,
|
|
|
|
// then the 16 bitScan/bitBlockBoundary bits, then the 16 bitAllocated bits.
|
|
|
|
// This layout makes it easier to iterate over the bits of a given type.
|
|
|
|
//
|
|
|
|
// The bitmap starts at mheap.arena_start and extends *backward* from
|
|
|
|
// there. On a 64-bit system the off'th word in the arena is tracked by
|
|
|
|
// the off/16+1'th word before mheap.arena_start. (On a 32-bit system,
|
|
|
|
// the only difference is that the divisor is 8.)
|
|
|
|
//
|
|
|
|
// To pull out the bits corresponding to a given pointer p, we use:
|
|
|
|
//
|
|
|
|
// off = p - (uintptr*)mheap.arena_start; // word offset
|
|
|
|
// b = (uintptr*)mheap.arena_start - off/wordsPerBitmapWord - 1;
|
|
|
|
// shift = off % wordsPerBitmapWord
|
|
|
|
// bits = *b >> shift;
|
|
|
|
// /* then test bits & bitAllocated, bits & bitMarked, etc. */
|
|
|
|
//
|
|
|
|
#define bitAllocated ((uintptr)1<<(bitShift*0)) /* block start; eligible for garbage collection */
|
|
|
|
#define bitScan ((uintptr)1<<(bitShift*1)) /* when bitAllocated is set */
|
|
|
|
#define bitMarked ((uintptr)1<<(bitShift*2)) /* when bitAllocated is set */
|
|
|
|
#define bitBlockBoundary ((uintptr)1<<(bitShift*1)) /* when bitAllocated is NOT set - mark for FlagNoGC objects */
|
|
|
|
|
|
|
|
#define bitMask (bitAllocated | bitScan | bitMarked)
|