@@ -68,9 +68,11 @@ struct MultiMemoryLowering : public Pass {
68
68
// properties will be set
69
69
Name module ;
70
70
Name base;
71
- // The initial page size of the combined memory
71
+ // The page size of the combined memory
72
+ uint8_t pageSizeLog2;
73
+ // The initial page count of the combined memory
72
74
Address totalInitialPages;
73
- // The max page size of the combined memory
75
+ // The max page count of the combined memory
74
76
Address totalMaxPages;
75
77
// There is no offset for the first memory, so offsetGlobalNames will always
76
78
// have a size that is one less than the count of memories at the time this
@@ -435,6 +437,7 @@ struct MultiMemoryLowering : public Pass {
435
437
: Builder::MemoryInfo::Memory64;
436
438
isShared = getFirstMemory ().shared ;
437
439
isImported = getFirstMemory ().imported ();
440
+ pageSizeLog2 = Memory::kDefaultPageSizeLog2 ;
438
441
for (auto & memory : wasm->memories ) {
439
442
// We are assuming that each memory is configured the same as the first
440
443
// and assert if any of the memories does not match this configuration
@@ -446,18 +449,21 @@ struct MultiMemoryLowering : public Pass {
446
449
Fatal () << " MultiMemoryLowering: only the first memory can be imported" ;
447
450
}
448
451
452
+ // Calculating the page size of the combined memory.
453
+ // This corresponds to the smaller granularity among combined memories
454
+ pageSizeLog2 = std::min (pageSizeLog2,memory->pageSizeLog2 );
455
+
449
456
// Calculating the total initial and max page size for the combined memory
450
457
// by totaling the initial and max page sizes for the memories in the
451
458
// module
452
- totalInitialPages = totalInitialPages + memory->initial ;
459
+ totalInitialPages = totalInitialPages + ( memory->initial << (memory-> pageSizeLog2 - pageSizeLog2)) ;
453
460
if (memory->hasMax ()) {
454
- totalMaxPages = totalMaxPages + memory->max ;
461
+ totalMaxPages = totalMaxPages + ( memory->max << (memory-> pageSizeLog2 - pageSizeLog2)) ;
455
462
}
456
463
}
457
464
// Ensuring valid initial and max page sizes that do not exceed the number
458
465
// of pages addressable by the pointerType
459
- Address maxSize =
460
- pointerType == Type::i32 ? Memory::kMaxSize32 : Memory::kMaxSize64 ;
466
+ Address maxSize = pointerType == Type::i32 ? 1ull <<(32 -pageSizeLog2) : 1ull <<(64 -pageSizeLog2);
461
467
if (totalMaxPages > maxSize || totalMaxPages == 0 ) {
462
468
totalMaxPages = Memory::kUnlimitedSize ;
463
469
}
@@ -504,9 +510,9 @@ struct MultiMemoryLowering : public Pass {
504
510
Name name = Names::getValidGlobalName (
505
511
*wasm, memory->name .toString () + " _byte_offset" );
506
512
offsetGlobalNames.push_back (std::move (name));
507
- addGlobal (name, offsetRunningTotal * Memory:: kPageSize );
513
+ addGlobal (name, offsetRunningTotal << pageSizeLog2 );
508
514
}
509
- offsetRunningTotal += memory->initial ;
515
+ offsetRunningTotal += memory->initial << (memory-> pageSizeLog2 - pageSizeLog2) ;
510
516
}
511
517
}
512
518
@@ -554,10 +560,10 @@ struct MultiMemoryLowering : public Pass {
554
560
functionName, Signature (pointerType, pointerType), {});
555
561
function->setLocalName (0 , " page_delta" );
556
562
auto pageSizeConst = [&]() {
557
- return builder.makeConst (Literal (Memory:: kPageSize ));
563
+ return builder.makeConst (Literal (wasm-> memories [memIdx]-> pageSizeLog2 ));
558
564
};
559
565
auto getOffsetDelta = [&]() {
560
- return builder.makeBinary (Abstract::getBinary (pointerType, Abstract::Mul ),
566
+ return builder.makeBinary (Abstract::getBinary (pointerType, Abstract::Shl ),
561
567
builder.makeLocalGet (0 , pointerType),
562
568
pageSizeConst ());
563
569
};
@@ -588,7 +594,8 @@ struct MultiMemoryLowering : public Pass {
588
594
builder.makeBinary (
589
595
EqInt32,
590
596
builder.makeMemoryGrow (
591
- builder.makeLocalGet (0 , pointerType), combinedMemory, memoryInfo),
597
+ builder.makeBinary ( Abstract::getBinary (pointerType, Abstract::Shl),
598
+ builder.makeLocalGet (0 , pointerType), builder.makeConst (Literal (wasm->memories [memIdx]->pageSizeLog2 - pageSizeLog2))) , combinedMemory, memoryInfo),
592
599
builder.makeConst (-1 )),
593
600
builder.makeReturn (builder.makeConst (-1 ))));
594
601
@@ -609,7 +616,7 @@ struct MultiMemoryLowering : public Pass {
609
616
// size
610
617
builder.makeBinary (
611
618
Abstract::getBinary (pointerType, Abstract::Sub),
612
- builder.makeBinary (Abstract::getBinary (pointerType, Abstract::Mul ),
619
+ builder.makeBinary (Abstract::getBinary (pointerType, Abstract::Shl ),
613
620
builder.makeLocalGet (sizeLocal, pointerType),
614
621
pageSizeConst ()),
615
622
getMoveSource (offsetGlobalName)),
@@ -646,11 +653,11 @@ struct MultiMemoryLowering : public Pass {
646
653
functionName, Signature (Type::none, pointerType), {});
647
654
Expression* functionBody;
648
655
auto pageSizeConst = [&]() {
649
- return builder.makeConst (Literal (Memory:: kPageSize ));
656
+ return builder.makeConst (Literal (pageSizeLog2 ));
650
657
};
651
658
auto getOffsetInPageUnits = [&](Name global) {
652
659
return builder.makeBinary (
653
- Abstract::getBinary (pointerType, Abstract::DivU ),
660
+ Abstract::getBinary (pointerType, Abstract::ShrU ),
654
661
builder.makeGlobalGet (global, pointerType),
655
662
pageSizeConst ());
656
663
};
@@ -697,6 +704,7 @@ struct MultiMemoryLowering : public Pass {
697
704
memory->base = base;
698
705
memory->module = module ;
699
706
}
707
+ memory->pageSizeLog2 = pageSizeLog2;
700
708
wasm->addMemory (std::move (memory));
701
709
}
702
710
0 commit comments