integrate

This commit is contained in:
dcode 2019-03-09 00:40:03 +01:00
parent 911a4bbaf2
commit 0ad9d560e0
7 changed files with 33 additions and 19 deletions

View File

@ -474,6 +474,9 @@ export namespace BuiltinSymbols {
export const memory_fill = "~lib/memory/memory.fill";
// std/gc.ts
export const iterateRoots = "~lib/gc/iterateRoots";
// internals
export const rt_classid = "~lib/builtins/__rt_classid";
export const rt_iterateroots = "~lib/builtins/__rt_iterateroots";
}
/** Compiles a call to a built-in function. */
@ -3591,9 +3594,17 @@ export function compileCall(
return module.createUnary(op, arg0);
}
// === GC integration =========================================================================
// === Internal runtime =======================================================================
case BuiltinSymbols.iterateRoots: {
case BuiltinSymbols.rt_classid: {
let type = evaluateConstantType(compiler, typeArguments, operands, reportNode);
compiler.currentType = Type.u32;
if (!type) return module.createUnreachable();
let classReference = type.classReference;
if (!classReference) return module.createUnreachable();
return module.createI32(classReference.prototype.classId);
}
case BuiltinSymbols.rt_iterateroots: {
if (
checkTypeAbsent(typeArguments, reportNode, prototype) |
checkArgsRequired(operands, 1, reportNode, compiler)

View File

@ -344,6 +344,9 @@ export class Program extends DiagnosticEmitter {
/** Memory allocation function. */
memoryAllocateInstance: Function | null = null;
/** Next class id. */
nextClassId: u32 = 1;
// gc integration
/** Whether a garbage collector is present or not. */
@ -2355,7 +2358,7 @@ export class FunctionPrototype extends DeclaredElement {
/** Constructs a new function prototype. */
constructor(
/** Simple na,e */
/** Simple name */
name: string,
/** Parent element, usually a file, namespace or class (if a method). */
parent: Element,
@ -2792,6 +2795,8 @@ export class ClassPrototype extends DeclaredElement {
overloadPrototypes: Map<OperatorKind, FunctionPrototype> = new Map();
/** Already resolved instances. */
instances: Map<string,Class> | null = null;
/** Unique class id. */
classId: u32 = 0;
constructor(
/** Simple name. */
@ -2813,6 +2818,8 @@ export class ClassPrototype extends DeclaredElement {
declaration
);
this.decoratorFlags = decoratorFlags;
this.classId = u32(this.program.nextClassId++);
assert(this.classId); // must not wrap around to 0
}
/** Gets the associated type parameter nodes. */

View File

@ -501,3 +501,6 @@ export namespace v8x16 {
}
@builtin export declare function start(): void;
@builtin export declare function __rt_classid<T>(): u32;
@builtin export declare function __rt_iterateroots(fn: (ref: usize) => void): void;

View File

@ -12,7 +12,6 @@
@inline export const HEADER_SIZE: usize = (offsetof<ManagedObject>() + AL_MASK) & ~AL_MASK;
import { AL_MASK, MAX_SIZE_32 } from "../internal/allocator";
import { iterateRoots } from "../gc";
/** Collector states. */
const enum State {
@ -142,7 +141,7 @@ function step(): void {
}
case State.IDLE: {
if (TRACE) trace("gc~step/IDLE");
iterateRoots(__gc_mark);
__rt_iterateroots(__gc_mark);
state = State.MARK;
if (TRACE) trace("gc~state = MARK");
break;
@ -163,7 +162,7 @@ function step(): void {
obj.hookFn(objToRef(obj));
} else {
if (TRACE) trace("gc~step/MARK finish");
iterateRoots(__gc_mark);
__rt_iterateroots(__gc_mark);
obj = iter.next;
if (obj === toSpace) {
let from = fromSpace;

View File

@ -1,7 +1,5 @@
/* tslint:disable */
@builtin export declare function iterateRoots(fn: (ref: usize) => void): void;
export namespace gc {
export function collect(): void {

View File

@ -25,7 +25,7 @@ export class HEADER {
@inline export const HEADER_MAGIC: u32 = 0xA55E4B17;
/** Aligns an allocation to actual block size. */
function ALIGN(payloadSize: usize): usize {
export function ALIGN(payloadSize: usize): usize {
// round up to power of 2, e.g. with HEADER_SIZE=8:
// 0 -> 2^3 = 8
// 1..8 -> 2^4 = 16
@ -36,7 +36,7 @@ function ALIGN(payloadSize: usize): usize {
}
/** Gets to the common runtime header of the specified reference. */
function UNREF(ref: usize): HEADER {
export function UNREF(ref: usize): HEADER {
assert(ref >= HEAP_BASE + HEADER_SIZE); // must be a heap object
var header = changetype<HEADER>(ref - HEADER_SIZE);
assert(header.classId == HEADER_MAGIC); // must be unregistered
@ -96,14 +96,10 @@ export function FREE(ref: usize): void {
memory.free(changetype<usize>(header));
}
function CLASSID<T>(): u32 {
return 1;
}
/** Registers a managed object with GC. Cannot be changed anymore afterwards. */
export function REGISTER<T>(ref: usize, parentRef: usize): void {
var header = UNREF(ref);
header.classId = CLASSID<T>();
header.classId = __rt_classid<T>();
if (GC) __REGISTER_IMPL(ref, parentRef);
}

View File

@ -142,7 +142,7 @@ declare namespace i8 {
export function parseInt(string: string, radix?: i32): i8;
}
/** Converts any other numeric value to a 16-bit signed integer. */
declare function i16(value: i8 | i16 | i32 | isize | u8 | u16 | u32 | usize | bool | f32 | f64): i8;
declare function i16(value: i8 | i16 | i32 | isize | u8 | u16 | u32 | usize | bool | f32 | f64): i16;
declare namespace i16 {
/** Smallest representable value. */
export const MIN_VALUE: i16;
@ -178,7 +178,7 @@ declare namespace isize {
export function parseInt(string: string, radix?: i32): isize;
}
/** Converts any other numeric value to an 8-bit unsigned integer. */
declare function u8(value: i8 | i16 | i32 | isize | u8 | u16 | u32 | usize | bool | f32 | f64): i8;
declare function u8(value: i8 | i16 | i32 | isize | u8 | u16 | u32 | usize | bool | f32 | f64): u8;
declare namespace u8 {
/** Smallest representable value. */
export const MIN_VALUE: u8;
@ -190,7 +190,7 @@ declare namespace u8 {
export function parseInt(string: string, radix?: i32): u8;
}
/** Converts any other numeric value to a 16-bit unsigned integer. */
declare function u16(value: i8 | i16 | i32 | isize | u8 | u16 | u32 | usize | bool | f32 | f64): i8;
declare function u16(value: i8 | i16 | i32 | isize | u8 | u16 | u32 | usize | bool | f32 | f64): u16;
declare namespace u16 {
/** Smallest representable value. */
export const MIN_VALUE: u16;
@ -202,7 +202,7 @@ declare namespace u16 {
export function parseInt(string: string, radix?: i32): u16;
}
/** Converts any other numeric value to a 32-bit unsigned integer. */
declare function u32(value: i8 | i16 | i32 | isize | u8 | u16 | u32 | usize | bool | f32 | f64): i32;
declare function u32(value: i8 | i16 | i32 | isize | u8 | u16 | u32 | usize | bool | f32 | f64): u32;
declare namespace u32 {
/** Smallest representable value. */
export const MIN_VALUE: u32;