@@ -4366,9 +4366,9 @@ int jsvGarbageCollect() {
4366
4366
}
4367
4367
4368
4368
#ifndef SAVE_ON_FLASH
4369
- static void _jsvDefragment_moveReferences (JsVarRef defragFromRef , JsVarRef defragToRef ) {
4369
+ static void _jsvDefragment_moveReferences (JsVarRef defragFromRef , JsVarRef defragToRef , unsigned int lastAllocated ) {
4370
4370
// find references!
4371
- for (JsVarRef vr = 1 ;vr <=jsVarsSize ;vr ++ ) {
4371
+ for (JsVarRef vr = 1 ;vr <=lastAllocated ;vr ++ ) {
4372
4372
JsVar * v = _jsvGetAddressOf (vr );
4373
4373
if ((v -> flags & JSV_VARTYPEMASK )!= JSV_UNUSED ) {
4374
4374
if (jsvIsFlatString (v )) {
@@ -4404,17 +4404,29 @@ void jsvDefragment() {
4404
4404
// garbage collect - removes cruft, also puts free list in order
4405
4405
jsvGarbageCollect ();
4406
4406
jshInterruptOff ();
4407
+ const unsigned int minMove = 20 ; // don't move vars back less than this or we're just wasting CPU time
4408
+ // find last allocated block of memory - speeds up searches!
4409
+ unsigned int lastAllocated = 0 ;
4410
+ for (JsVarRef i = 1 ;i <=jsVarsSize ;i ++ ) {
4411
+ JsVar * v = _jsvGetAddressOf (i );
4412
+ if ((v -> flags & JSV_VARTYPEMASK )!= JSV_UNUSED ) {
4413
+ if (jsvIsFlatString (v )) {
4414
+ i += 1 + (unsigned int )jsvGetFlatStringBlocks (v ); // skip forward
4415
+ }
4416
+ lastAllocated = i ;
4417
+ }
4418
+ }
4407
4419
// the var we're planning on writing to
4408
4420
JsVarRef defragToRef = 1 ;
4409
4421
// now for all blocks in memory...
4410
- for (JsVarRef defragFromRef = 1 ;defragFromRef <=jsVarsSize ;defragFromRef ++ ) {
4422
+ for (JsVarRef defragFromRef = 1 ;defragFromRef <=lastAllocated ;defragFromRef ++ ) {
4411
4423
// First move our destination block on until we find an UNUSED one...
4412
4424
JsVar * defragTo = _jsvGetAddressOf (defragToRef );
4413
4425
while ((defragTo -> flags & JSV_VARTYPEMASK )!= JSV_UNUSED ) {
4414
4426
if (jsvIsFlatString (defragTo )) {
4415
4427
defragToRef += 1 + (unsigned int )jsvGetFlatStringBlocks (defragTo ); // skip forward
4416
4428
} else defragToRef ++ ;
4417
- if (defragToRef > jsVarsSize ) { // no more free blocks? quit
4429
+ if (defragToRef > lastAllocated ) { // no more free blocks? quit
4418
4430
jsvCreateEmptyVarList ();
4419
4431
jshInterruptOn ();
4420
4432
return ;
@@ -4432,11 +4444,11 @@ void jsvDefragment() {
4432
4444
from defragToRef trying to see how many blocks we can move */
4433
4445
JsVarRef fsToRef = defragToRef ;
4434
4446
bool isClear = false;
4435
- while (!isClear && fsToRef < defragFromRef ) {
4447
+ while (!isClear && ( defragFromRef > fsToRef + minMove ) ) {
4436
4448
isClear = true;
4437
4449
// check area in fsToRef to see if it's clear
4438
- for (int i = 0 ;i < blocksNeeded ;i ++ ) {
4439
- // TODO: what if we overlap with ourself?? would have to ensure we don't clear overlapping area
4450
+ for (unsigned int i = 0 ;i < blocksNeeded ;i ++ ) {
4451
+ // TODO: what if we want to overlap with ourself?? would have to ensure we don't clear overlapping area
4440
4452
if ((_jsvGetAddressOf (fsToRef + i )-> flags & JSV_VARTYPEMASK )!= JSV_UNUSED ) {
4441
4453
isClear = false; // it's not clear!
4442
4454
fsToRef += i ; // jump to this used block
@@ -4450,33 +4462,32 @@ void jsvDefragment() {
4450
4462
if (jsvIsFlatString (v )) {
4451
4463
fsToRef += 1 + (unsigned int )jsvGetFlatStringBlocks (v ); // skip forward
4452
4464
} else fsToRef ++ ;
4453
- if (fsToRef <= jsVarsSize )
4454
- v = _jsvGetAddressOf (defragToRef );
4465
+ if (fsToRef <= lastAllocated )
4466
+ v = _jsvGetAddressOf (fsToRef );
4455
4467
else
4456
4468
break ; // end of memory
4457
4469
}
4458
4470
}
4459
4471
}
4460
- if (isClear && (defragFromRef > fsToRef )) {
4472
+ if (isClear && (defragFromRef > fsToRef + minMove )) { // can we move it earlier in memory?
4461
4473
//jsiConsolePrintf("Move FlatString %d -> %d\n", defragFromRef, fsToRef);
4462
4474
defragTo = _jsvGetAddressOf (fsToRef );
4463
4475
// copy data and clear old var
4464
4476
memmove (defragTo , defragFrom , sizeof (JsVar )* blocksNeeded );
4465
4477
memset (defragFrom , 0 , sizeof (JsVar )* blocksNeeded );
4466
4478
// copy references
4467
- _jsvDefragment_moveReferences (defragFromRef , defragToRef );
4479
+ _jsvDefragment_moveReferences (defragFromRef , fsToRef , lastAllocated );
4468
4480
}
4469
4481
}
4470
4482
defragFromRef += blocksNeeded - 1 ; // skip forward (for loop adds 1)
4471
- // skip flat strings for now
4472
4483
} else if (canMove ) { // moving a single var
4473
- if (defragFromRef > defragToRef ) { // can we move back ?
4484
+ if (defragFromRef > defragToRef + minMove ) { // can we move it earlier in memory ?
4474
4485
//jsiConsolePrintf("Move JsVar %d -> %d\n", defragFromRef, defragToRef);
4475
4486
// copy data and clear old var
4476
4487
* defragTo = * defragFrom ;
4477
4488
memset (defragFrom , 0 , sizeof (JsVar )); // set flags to 0=unused
4478
4489
// copy references
4479
- _jsvDefragment_moveReferences (defragFromRef , defragToRef );
4490
+ _jsvDefragment_moveReferences (defragFromRef , defragToRef , lastAllocated );
4480
4491
}
4481
4492
}
4482
4493
}
0 commit comments