原文
http://www.hpl.hp.com/personal/Hans_Boehm/gc/porting.html
The collector is designed to be relatively easy to port, but is not portable code per se.
收集器被设计的相对比较好移植,但不是每个代码段都可以移植(*se 应该是 section 的缩写)
The collector inherently has to perform operations, such as scanning the stack(s), that are not possible in portable C code.
收集器内在的必须执行一些活动,例如扫描栈,这是不可能在可移植的C代码中(实现)的
All of the following assumes that the collector is being ported to a byte-addressable 32- or 64-bit machine.
下面的所有(内容)假设收集器被移植到一个可单字节寻址 的32或64位的机器上
Currently all successful ports to 64-bit machines involve LP64 targets.
当前所有成功移植到64位机器上(的情况)需要LP64目标(*没看懂)
The code base includes some provisions for P64 targets (notably win64), but that has not been tested.
代码包括了一些为(移植到)P64目标的条文(特别是win64),但还未被测试
You are hereby discouraged from attempting a port to non-byte-addressable, or 8-bit, or 16-bit machines.
尝试移植到一个无字节寻址能力的或者8位、16为的机器上,这种方式将会使得你灰心丧气(*大概说是搞不成吧,没看懂)
The difficulty of porting the collector varies greatly depending on the needed functionality.
收集器的变化的移植难度取决于必须的功能性函数
In the simplest case, only some small additions are needed for the include/private/gcconfig.h file.
对最简单的情况,仅仅是 在include/private/gcconfig.h 文件中做很少的添加.
This is described in the following section.
这(方面)在下一段中有描述.
Later sections discuss some of the optional features, which typically involve more porting effort.
后面的一节讨论了一些移植工作中典型的可选的特征.
Note that the collector makes heavy use of ifdefs.
(需要)指出收集器(的实现)着重使用了 ifdefs(条件编译的方式)
Unlike some other software projects, we have concluded repeatedly that this is preferable to system dependent files, with code duplicated between the files.
不象一些其他的软件工程,我们反复断定(用ifdefs)(会比)在文件中复制代码,对系统支持文件来说更好.
However, to keep this manageable, we do strongly believe in indenting ifdefs correctly (for historical reasons usually without the leading sharp sign).
然而,为了使得(代码)可管理,我们强烈主张正确的缩排 ifdefs(这些条件编译选项)(历史原因,通常没有前导清晰标记)
(Separate source files are of course fine if they don't result in code duplication.)
如果(以上情况)不发生,在代码复制(的情况下),分割源代码文件当然是好的
If neither thread support, nor tracing of dynamic library data is required, these are often the only changes you will need to make.
如果即没有线程支持也没有跟踪(功能,*我觉得他指的是功能)则动态库数据是必要的,这些(应该指下面的N条)是通常要做变更的(地方).
The gcconfig.h file consists of three sections:
gcconfig.h 这个文件由三个段组成:
It is relatively straightforward to add a new entry here. But please try to be consistent with the existing code. In particular, 64-bit variants of 32-bit architectures general are not treated as a new architecture. Instead we explicitly test for 64-bit-ness in the few places in which it matters. (The notable exception here is I386 and X86_64. This is partially historical, and partially justified by the fact that there are arguably more substantial architecture and ABI differences here than for RISC variants.)
这里添加一个新的入口相对比较容易.但请尽量保持和现有的代码一致.特别是,32位体系结构下64位变量一般不被判断成
一个新的体系结构.
on GNU-based systems, cpp -dM empty_source_file.c seems to generate a set of predefined macros. On some other systems, the "verbose" compiler option may do so, or the manual page may list them.
This section contains a subsection for each architecture (enclosed in a suitable ifdef. Each subsection usually contains some architecture-dependent defines, followed by several sets of OS-dependent defines, again enclosed in ifdefs.
The following macros must be defined correctly for each architecture and operating system:
对每个体系结构和操作系统以下这些宏必须定义正确:
In some cases, you may have to add additional platform-specific code to other files.
在某中情况下,(用户)也许必须添加附加的平台特性代码到一些文件中
A likely candidate is the implementation of GC_with_callee_saves_pushed in mach_dep.c.
mach_dep.c 中 GC_width_callesaves_pushed 给出了一个类似实现
This ensure that register contents that the collector must trace from are copied to the stack.
收集器必须跟踪那些复制到栈的确认注册目录(*没搞懂)
Typically this can be done portably, but on some platforms it may require assembly code, or just tweaking of conditional compilation tests.
通常情况下这些将很容易做到,但是在一些平台中也许会需要用到汇编代码,或者调整条件编译测试的tweaking(*没搞懂)
For GC7, if your platform supports getcontext(), then definining the macro UNIX_LIKE for your OS in gcconfig.h (if it isn't defined there already) is likely to solve the problem.
在 GC7中,如果你的平台支持 getcontext(),那么在 gcconfig.h中为你的操作系统定义UNIX_LIKE宏 (如果在其中还没被定义)将可能解决你的问题
otherwise, if you are using gcc, _builtin_unwind_init() will be used, and should work fine.
否则,如果你使用gcc,,你将会用到 _builtin_unwind_init()(这个函数),它会帮助你很好的完成工作
If that is not applicable either, the implementation will try to use setjmp().
如果没办法找到适用的,(gc)的实现将尝试使用setjmp()(这个函数).
This will work if your setjmp implementation saves all possibly pointer-valued registers into the buffer, as opposed to trying to unwind the stack at longjmp time.
如果setjmp(这个函数,*估计是让自己实现的),保存了所可能的 pointer-valued(*不知道啥意思)注册到缓存中,(gc)将开始工作,另一方面使用longjamp(这个函数)尝试释放堆栈上的内容.
The setjmp_test test tries to determine this, but often doesn't get it right.
setjmp_test(这个函数)将设法决定这些情况,但是它常常不搞清楚.(*它都搞不清楚我们咋搞清楚呢?)
In GC6.x versions of the collector, tracing of registers was more commonly handled with assembly code.
在 GC6.X各个版本的回收器中,跟踪注册通常是通过汇编代码来处理的.
In GC7, this is generally to be avoided.
在 GC7,这些通常被避免
Most commonly os_dep.c will not require attention, but see below.
通常情况下os_dep.c将不要求注意,但要参考下面(的内容)
Supporting threads requires that the collector be able to find and suspend all threads potentially accessing the garbage-collected heap, and locate any state associated with each thread that must be traced.
支持线程需要收集器可以查找和挂起所有线程
The functionality needed for thread support is generally implemented in one or more files specific to the particular thread interface.
线程支持功能通常在一个或者多个文件中实现特定线程接口
For example, somewhat portable pthread support is implemented in pthread_support.c and pthread_stop_world.c.
例如,一些可移植的线程支持功能分别在 pthread_support.c和pthread_stop-world.c中实现.
The essential functionality consists of
基本功能表
These very often require that the garbage collector maintain its own data structures to track active threads.
用来跟踪活动的线程时,垃圾回收器会维护他自己的数据结构,这些(功能,指上面这几个函数)经常是必须的
In addition, LOCK and UNLOCK must be implemented in gc_locks.h
此外,在 gc_locks.h中(定义的)LOCK(锁) 和 UNLOCK (解锁)必须实现
The easiest case is probably a new pthreads platform on which threads can be stopped with signals. In this case, the changes involve:
Non-preemptive threads packages will probably require further work. Similarly thread-local allocation and parallel marking requires further work in pthread_support.c, and may require better atomic_ops support.
So long as DATASTART and DATAEND are defined correctly, the collector will trace memory reachable from file scope or static variables defined as part of the main executable. This is sufficient if either the program is statically linked, or if pointers to the garbage-collected heap are never stored in non-stack variables defined in dynamic libraries.
If dynamic library data sections must also be traced, then
Implementations that scan for writable data segments are error prone, particularly in the presence of threads. They frequently result in race conditions when threads exit and stacks disappear. They may also accidentally trace large regions of graphics memory, or mapped files. On at least one occasion they have been known to try to trace device memory that could not safely be read in the manner the GC wanted to read it.
It is usually safer to walk the dynamic linker data structure, especially if the linker exports an interface to do so. But beware of poorly documented locking behavior in this case.
For incremental and generational collection to work, os_dep.c must contain a suitable "virtual dirty bit" implementation, which allows the collector to track which heap pages (assumed to be a multiple of the collectors block size) have been written during a certain time interval.
为了增量回收工作,os_dep.c必须包含一个允许回收器跟踪(内存)堆的分页(假设是 回收器(使用的)块大小的倍数)在一个确定的时间间隔被写的,类似"虚拟页面重写标志位"的实现
The collector provides several implementations, which might be adapted.
回收器本身提供了一些也许可以适配(通用)的实现.
The default (DEFAULT_VDB) is a placeholder which treats all pages as having been written.
默认的(DEFAULT_VDB)是一个判断所有页是否已经被写的占位符.
This ensures correctness, but renders incremental and generational collection essentially useless.
If stack traces in objects are need for debug support, GC_dave_callers and GC_print_callers must be implemented.
如果要支持调试(环境),对象的堆栈追踪功能是必须的 ,GC_dave_callers 和 GC_print_callers
(两个,看样子是函数,具体是啥,搜索过所有地方没见到有范例)必须实现
This is an initial pass at porting guidelines. Some things have no doubt been overlooked.
这是个初步通过的移植指导. 一些事毫无疑问的(可能)被忽略掉了