Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Memory improvements + Type analysis #56

Open
wants to merge 40 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 5 commits
Commits
Show all changes
40 commits
Select commit Hold shift + click to select a range
ce5a503
codegen: optimize string allocation
BobVarioa Jun 1, 2024
7d55544
codegen: fix minor string bugs
BobVarioa Jun 2, 2024
73bf981
codegen: improve string initialization code size
BobVarioa Jun 2, 2024
96b289f
codegen: revert i64 string writing
BobVarioa Jun 2, 2024
5a2ae98
codegen: allow multiple pages for strings
BobVarioa Jun 2, 2024
48fb0f1
codegen: convert constant strings to string buffers
BobVarioa Jun 3, 2024
8601a01
codegen: replace concat strings with function implementation
BobVarioa Jun 3, 2024
479ef95
codegen: un-asm String.concat
BobVarioa Jun 3, 2024
4044d85
allocators: actually allow multiple pages for strings
BobVarioa Jun 3, 2024
571a551
builtins/ecma262: remove unnecessary string buffer
BobVarioa Jun 3, 2024
dcd334b
builtins: seperate internal functions into a seperate file
BobVarioa Jun 4, 2024
042eb94
builtins: replace Porffor.s/bs with actual allocations
BobVarioa Jun 4, 2024
ba07507
builtins: rewrite some builtins to allocate memory on the fly
BobVarioa Jun 4, 2024
501ebaf
builtins/date: cleanup Porffor internal methods
BobVarioa Jun 4, 2024
b8983bb
codegen: reenable js type analysis
BobVarioa Jun 4, 2024
3b3eb2f
builtins: rename porffor.ts to utils.ts
BobVarioa Jun 4, 2024
32a8281
codegen: move string initialization to the beginning of a program
BobVarioa Jun 4, 2024
570c49c
builtins: eliminate some unnecessary locals
BobVarioa Jun 4, 2024
9359bb9
builtins/string: properly cast argument of includes to string
BobVarioa Jun 4, 2024
b18279a
codegen: fix strings added at precompilation
BobVarioa Jun 5, 2024
1f76666
builtins/string: fix string.concat
BobVarioa Jun 5, 2024
bb3c2b7
builtins: fix some types
BobVarioa Jun 5, 2024
aed8528
builtins/string: rewrite string.trim
BobVarioa Jun 5, 2024
d60527e
builtins/symbol: rewrite symbols to not use a page
BobVarioa Jun 5, 2024
b44e299
builtins/utils: rewrite string methods to avoid looping
BobVarioa Jun 5, 2024
67c63a5
codegen: overhaul js type analysis
BobVarioa Jun 5, 2024
0017d35
chore: merge from main
BobVarioa Jun 5, 2024
76e2dca
allocators: use map.has, not a falsy check
BobVarioa Jun 6, 2024
5c504e2
builtins/string: convert compare strings into a builtin
BobVarioa Jun 6, 2024
f7bc3c6
builtins/array: allocate -> allocatePage
BobVarioa Jun 6, 2024
f8586e1
builtins/string: fix charcode for nan values
BobVarioa Jun 6, 2024
3089e7d
codegen/types: fix typo in prototype return type checking
BobVarioa Jun 6, 2024
0004c8c
codegen: add Porffor.allocateNamedPage
BobVarioa Jun 7, 2024
3f04959
builtins/symbol: fix symbol implementation
BobVarioa Jun 7, 2024
6e6ebf2
builtins/string: revert change to string constructor
BobVarioa Jun 7, 2024
3e1a432
builtins/symbol: fix typo
BobVarioa Jun 7, 2024
3da07f4
codegen: fix nonbytestring strings
BobVarioa Jun 7, 2024
7d97eb7
builtins/string: fix trim for strings
BobVarioa Jun 7, 2024
57437a6
codegen: remove makeStringBuffer
BobVarioa Jun 7, 2024
0f94882
chore: regenerate builtins
BobVarioa Jun 7, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions compiler/allocators.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ export class StaticAllocator {

alloc({ scope, pages }, name, { itemType }) {
const reason = `${this.allocType(itemType)}: ${Prefs.scopedPageNames ? (scope.name + '/') : ''}${name}`;
if (Prefs.allocLog) console.log(reason)

if (pages.has(reason)) return number(this.ptr(pages.get(reason).ind), Valtype.i32);

Expand All @@ -52,6 +53,51 @@ export class StaticAllocator {

return number(this.ptr(ind), Valtype.i32);
}

stringPageIndex = 0;

allocString(pages, str) {
let page = { ind: -1, strs: [], strIndex: new Map(), byteSize: 0 }
let size = Prefs.bytestring ? 1 : 2;
for (let i = 0; i < str.length; i++) {
if (str.charCodeAt(i) > 0xFF) {
size = 2;
break;
}
}
pages.hasAnyString = true;
if (size == 1) pages.hasByteString = true;
else pages.hasString = true;

for (let i = 0; i < this.stringPageIndex; i++) {
if (pages.has(`strings${i}`)) {
const p = pages.get(`strings${i}`);
const index = p.strIndex.get(str);
if (index) {
if (Prefs.allocLog) console.log("cstr/ref: "+ str)
return [p.strs[index].ptr, true];
}
if ((p.byteSize + (4 + str.length * size)) >= pageSize) {
page = p;
break;
}
}
}
if (page.ind == -1) {
const ind = pages.size;
page.ind = ind;
pages.set(`strings${this.stringPageIndex}`, page);
this.stringPageIndex++;
}

let ptr = this.ptr(page.ind) + page.byteSize;
page.byteSize += 4 + str.length * size; // u32 + u16[len] (or u8)
const index = page.strs.push({ str, ptr, size }) - 1;
page.strIndex.set(str, index);

if (Prefs.allocLog) console.log("cstr/init: "+ str)
return [ptr, false];
}
}

export class GrowAllocator {
Expand Down
152 changes: 151 additions & 1 deletion compiler/builtins/string_f64.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,154 @@ import type {} from './porffor.d.ts';
export const String = function (value: any): bytestring {
if (!new.target && Porffor.rawType(value) == Porffor.TYPES.symbol) return __Symbol_prototype_toString(value);
return __ecma262_ToString(value);
};
};

export const __String_prototype_concat = (_this: string, arg: string) => {
CanadaHonk marked this conversation as resolved.
Show resolved Hide resolved
// todo: convert left and right to strings if not
// todo: optimize by looking up names in arrays and using that if exists?
// todo: optimize this if using literals/known lengths?
let out: string = Porffor.s``;
Porffor.wasm`
local leftLength i32
local leftPtr i32
local rightLength i32
local rightPtr i32
local outPtr i32

local.get ${_this}
i32.to_u
local.set leftPtr

local.get ${arg}
i32.to_u
local.set rightPtr

local.get ${out}
i32.to_u
local.set outPtr

;; calculate length
local.get outPtr

local.get leftPtr
i32.load 0 0
local.tee leftLength
local.get rightPtr

i32.load 0 0
local.tee rightLength
i32.add
;; store out length
i32.store 0 0
;; copy left
;; dst = out pointer + length size
local.get outPtr
i32.const 4
i32.add
;; src = left pointer + length size
local.get leftPtr
i32.const 4
i32.add

local.get leftLength
i32.const
i32.mul
memory_copy 0 0

;; copy right
;; dst = out pointer + length size + left length * sizeof valtype
local.get outPtr
i32.const 4
i32.add
local.get leftLength
i32.const 2
i32.mul
i32.add
;; src = right pointer + length size
local.get rightPtr
i32.const 4
i32.add
;; size = right length * sizeof valtype
local.get rightLength
i32.const 2
i32.mul
memory_copy 0 0
`;

return out;
};

export const __ByteString_prototype_concat = (_this: bytestring, arg: bytestring) => {
// todo: convert left and right to strings if not
// todo: optimize by looking up names in arrays and using that if exists?
// todo: optimize this if using literals/known lengths?
let out: bytestring = Porffor.bs``;
Porffor.wasm`
local leftLength i32
local leftPtr i32
local rightLength i32
local rightPtr i32
local outPtr i32

local.get ${_this}
i32.to_u
local.set leftPtr

local.get ${arg}
i32.to_u
local.set rightPtr

local.get ${out}
i32.to_u
local.set outPtr

;; calculate length
local.get outPtr

local.get leftPtr
i32.load 0 0
local.tee leftLength
local.get rightPtr

i32.load 0 0
local.tee rightLength
i32.add
;; store out length
i32.store 0 0
;; copy left
;; dst = out pointer + length size
local.get outPtr
i32.const 4
i32.add
;; src = left pointer + length size
local.get leftPtr
i32.const 4
i32.add

local.get leftLength
;; i32.const 1
;; i32.mul
memory_copy 0 0

;; copy right
;; dst = out pointer + length size + left length * sizeof valtype
local.get outPtr
i32.const 4
i32.add
local.get leftLength
;; i32.const 1
;; i32.mul
i32.add
;; src = right pointer + length size
local.get rightPtr
i32.const 4
i32.add
;; size = right length * sizeof valtype
local.get rightLength
;; i32.const 1
;; i32.mul
memory_copy 0 0
`;
return out;
};

Loading