4
4
// -------------------------------------------------------------------------------------------------------
5
5
#include " Backend.h"
6
6
7
-
7
+ # if !FLOATVAR
8
8
CodeGenNumberThreadAllocator::CodeGenNumberThreadAllocator (Recycler * recycler)
9
9
: recycler(recycler), currentNumberSegment(nullptr ), currentChunkSegment(nullptr ),
10
10
numberSegmentEnd(nullptr ), currentNumberBlockEnd(nullptr ), nextNumber(nullptr ), chunkSegmentEnd(nullptr ),
@@ -245,7 +245,6 @@ CodeGenNumberAllocator::CodeGenNumberAllocator(CodeGenNumberThreadAllocator * th
245
245
}
246
246
247
247
// We should never call this function if we are using tagged float
248
- #if !FLOATVAR
249
248
Js::JavascriptNumber *
250
249
CodeGenNumberAllocator::Alloc ()
251
250
{
@@ -274,7 +273,7 @@ CodeGenNumberAllocator::Alloc()
274
273
this ->chunkTail ->numbers [this ->currentChunkNumberCount ++] = newNumber;
275
274
return newNumber;
276
275
}
277
- # endif
276
+
278
277
279
278
CodeGenNumberChunk *
280
279
CodeGenNumberAllocator::Finalize ()
@@ -290,16 +289,12 @@ CodeGenNumberAllocator::Finalize()
290
289
return finalizedChunk;
291
290
}
292
291
293
- /* static */
294
- uint
295
- XProcNumberPageSegmentImpl::GetSizeCat ()
296
- {
297
- return (uint)HeapInfo::GetAlignedSizeNoCheck (sizeof (Js::JavascriptNumber));
298
- }
299
-
300
292
301
- Js::JavascriptNumber* XProcNumberPageSegmentImpl::AllocateNumber (HANDLE hProcess, double value, Js::StaticType* numberTypeStatic, void * javascriptNumberVtbl)
293
+ uint XProcNumberPageSegmentImpl::sizeCat = sizeof (Js::JavascriptNumber);
294
+ Js::JavascriptNumber* XProcNumberPageSegmentImpl::AllocateNumber (Func* func, double value)
302
295
{
296
+ HANDLE hProcess = func->GetThreadContextInfo ()->GetProcessHandle ();
297
+
303
298
XProcNumberPageSegmentImpl* tail = this ;
304
299
305
300
if (this ->pageAddress != 0 )
@@ -309,39 +304,54 @@ Js::JavascriptNumber* XProcNumberPageSegmentImpl::AllocateNumber(HANDLE hProcess
309
304
tail = (XProcNumberPageSegmentImpl*)tail->nextSegment ;
310
305
}
311
306
312
- if (tail->pageAddress + tail->committedEnd - tail->allocEndAddress >= GetSizeCat () )
307
+ if (tail->pageAddress + tail->committedEnd - tail->allocEndAddress >= sizeCat )
313
308
{
314
309
auto number = tail->allocEndAddress ;
315
- tail->allocEndAddress += GetSizeCat () ;
310
+ tail->allocEndAddress += sizeCat ;
316
311
317
- Js::JavascriptNumber localNumber (value, numberTypeStatic
318
312
#if DBG
319
- , true
313
+ Js::JavascriptNumber localNumber (value, (Js::StaticType*)func->GetScriptContextInfo ()->GetNumberTypeStaticAddr (), true );
314
+ #else
315
+ Js::JavascriptNumber localNumber (value, (Js::StaticType*)func->GetScriptContextInfo ()->GetNumberTypeStaticAddr ());
320
316
#endif
321
- ) ;
317
+ Js::JavascriptNumber* pLocalNumber = &localNumber ;
322
318
319
+ #ifdef RECYCLER_MEMORY_VERIFY
320
+ if (func->GetScriptContextInfo ()->IsRecyclerVerifyEnabled ())
321
+ {
322
+ pLocalNumber = (Js::JavascriptNumber*)alloca (sizeCat);
323
+ memset (pLocalNumber, Recycler::VerifyMemFill, sizeCat);
324
+ Recycler::FillPadNoCheck (pLocalNumber, sizeof (Js::JavascriptNumber), sizeCat, false );
325
+ pLocalNumber = new (pLocalNumber) Js::JavascriptNumber (localNumber);
326
+ }
327
+ #endif
323
328
// change vtable to the remote one
324
- *(void **)&localNumber = javascriptNumberVtbl ;
329
+ *(void **)pLocalNumber = ( void *)func-> GetScriptContextInfo ()-> GetVTableAddress (VTableValue::VtableJavascriptNumber) ;
325
330
326
331
// initialize number by WriteProcessMemory
327
332
SIZE_T bytesWritten;
328
- WriteProcessMemory (hProcess, (void *)number, &localNumber, sizeof (localNumber), &bytesWritten);
333
+ if (!WriteProcessMemory (hProcess, (void *)number, pLocalNumber, sizeCat, &bytesWritten)
334
+ || bytesWritten != sizeCat)
335
+ {
336
+ Output::Print (_u (" FATAL ERROR: WriteProcessMemory failed, GLE: %d\n " ), GetLastError ());
337
+ Js::Throw::FatalInternalError (); // TODO: don't bring down whole server process, but pass the last error to main process
338
+ }
329
339
330
340
return (Js::JavascriptNumber*) number;
331
341
}
332
342
333
343
// alloc blocks
334
- if (( void *) tail->committedEnd < tail->GetEndAddress ())
344
+ if (tail->GetCommitEndAddress () < tail->GetEndAddress ())
335
345
{
336
- Assert ((unsigned int )((char *)tail->GetEndAddress () - (char *)tail->committedEnd ) >= BlockSize);
346
+ Assert ((unsigned int )((char *)tail->GetEndAddress () - (char *)tail->GetCommitEndAddress () ) >= BlockSize);
337
347
// TODO: implement guard pages (still necessary for OOP JIT?)
338
348
auto ret = ::VirtualAllocEx (hProcess, tail->GetCommitEndAddress (), BlockSize, MEM_COMMIT, PAGE_READWRITE);
339
349
if (!ret)
340
350
{
341
351
Js::Throw::OutOfMemory ();
342
352
}
343
353
tail->committedEnd += BlockSize;
344
- return AllocateNumber (hProcess , value, numberTypeStatic, javascriptNumberVtbl );
354
+ return AllocateNumber (func , value);
345
355
}
346
356
}
347
357
@@ -354,12 +364,11 @@ Js::JavascriptNumber* XProcNumberPageSegmentImpl::AllocateNumber(HANDLE hProcess
354
364
355
365
if (tail->pageAddress == 0 )
356
366
{
357
- tail = new (tail) XProcNumberPageSegmentImpl ();
358
367
tail->pageAddress = (intptr_t )pages;
359
368
tail->allocStartAddress = this ->pageAddress ;
360
369
tail->allocEndAddress = this ->pageAddress ;
361
370
tail->nextSegment = nullptr ;
362
- return AllocateNumber (hProcess , value, numberTypeStatic, javascriptNumberVtbl );
371
+ return AllocateNumber (func , value);
363
372
}
364
373
else
365
374
{
@@ -370,15 +379,40 @@ Js::JavascriptNumber* XProcNumberPageSegmentImpl::AllocateNumber(HANDLE hProcess
370
379
}
371
380
seg = new (seg) XProcNumberPageSegmentImpl ();
372
381
tail->nextSegment = seg;
373
- return seg->AllocateNumber (hProcess , value, numberTypeStatic, javascriptNumberVtbl );
382
+ return seg->AllocateNumber (func , value);
374
383
}
375
384
}
376
385
377
386
378
387
XProcNumberPageSegmentImpl::XProcNumberPageSegmentImpl ()
379
388
{
380
- this ->blockIntegratedSize = 0 ;
381
- this ->pageSegment = 0 ;
389
+ memset (this , 0 , sizeof (XProcNumberPageSegment));
390
+ }
391
+
392
+ void XProcNumberPageSegmentImpl::Initialize (bool recyclerVerifyEnabled, uint recyclerVerifyPad)
393
+ {
394
+ size_t allocSize = sizeof (Js::JavascriptNumber);
395
+ #ifdef ENABLE_DEBUG_CONFIG_OPTIONS
396
+ allocSize += Js::Configuration::Global.flags .NumberAllocPlusSize ;
397
+ #endif
398
+ #ifdef RECYCLER_MEMORY_VERIFY
399
+ // TODO: share same pad size with main process
400
+ if (recyclerVerifyEnabled)
401
+ {
402
+ size_t padAllocSize = AllocSizeMath::Add (sizeof (Js::JavascriptNumber) + sizeof (size_t ), recyclerVerifyPad);
403
+ allocSize = padAllocSize < allocSize ? allocSize : padAllocSize;
404
+ }
405
+ #endif
406
+
407
+ allocSize = (uint)HeapInfo::GetAlignedSizeNoCheck (allocSize);
408
+
409
+ if (BlockSize%allocSize != 0 )
410
+ {
411
+ // align allocation sizeCat to be 2^n to make integration easier
412
+ allocSize = BlockSize / (1 << (Math::Log2 (BlockSize / allocSize)));
413
+ }
414
+
415
+ sizeCat = allocSize;
382
416
}
383
417
384
418
Js::JavascriptNumber** ::XProcNumberPageSegmentManager::RegisterSegments(XProcNumberPageSegment* segments)
@@ -390,7 +424,7 @@ Js::JavascriptNumber** ::XProcNumberPageSegmentManager::RegisterSegments(XProcNu
390
424
size_t totalCount = 0 ;
391
425
while (temp)
392
426
{
393
- totalCount += (temp->allocEndAddress - temp->allocStartAddress ) / XProcNumberPageSegmentImpl::GetSizeCat () ;
427
+ totalCount += (temp->allocEndAddress - temp->allocStartAddress ) / XProcNumberPageSegmentImpl::sizeCat ;
394
428
temp = (XProcNumberPageSegmentImpl*)temp->nextSegment ;
395
429
}
396
430
@@ -400,18 +434,15 @@ Js::JavascriptNumber** ::XProcNumberPageSegmentManager::RegisterSegments(XProcNu
400
434
int count = 0 ;
401
435
while (temp)
402
436
{
403
- auto start = temp->allocStartAddress ;
404
- while (start < temp->allocEndAddress )
437
+ while (temp->allocStartAddress < temp->allocEndAddress )
405
438
{
406
- numbers[count] = (Js::JavascriptNumber*)start ;
439
+ numbers[count] = (Js::JavascriptNumber*)temp-> allocStartAddress ;
407
440
count++;
408
- start += XProcNumberPageSegmentImpl::GetSizeCat () ;
441
+ temp-> allocStartAddress += XProcNumberPageSegmentImpl::sizeCat ;
409
442
}
410
443
temp = (XProcNumberPageSegmentImpl*)temp->nextSegment ;
411
444
}
412
445
413
-
414
-
415
446
AutoCriticalSection autoCS (&cs);
416
447
if (this ->segmentsList == nullptr )
417
448
{
@@ -430,16 +461,10 @@ Js::JavascriptNumber** ::XProcNumberPageSegmentManager::RegisterSegments(XProcNu
430
461
return numbers;
431
462
}
432
463
433
- void XProcNumberPageSegmentManager::GetFreeSegment (XProcNumberPageSegment * seg )
464
+ XProcNumberPageSegment * XProcNumberPageSegmentManager::GetFreeSegment (Memory::ArenaAllocator* alloc )
434
465
{
435
466
AutoCriticalSection autoCS (&cs);
436
467
437
- if (segmentsList == nullptr )
438
- {
439
- new (seg) XProcNumberPageSegmentImpl ();
440
- return ;
441
- }
442
-
443
468
auto temp = segmentsList;
444
469
auto prev = &segmentsList;
445
470
while (temp)
@@ -449,13 +474,17 @@ void XProcNumberPageSegmentManager::GetFreeSegment(XProcNumberPageSegment * seg)
449
474
*prev = (XProcNumberPageSegmentImpl*)temp->nextSegment ;
450
475
451
476
// remove from the list
452
- memcpy (seg, temp, sizeof (XProcNumberPageSegment));
477
+ XProcNumberPageSegment * seg = (XProcNumberPageSegment *)AnewStructZ (alloc, XProcNumberPageSegmentImpl);
478
+ temp->nextSegment = 0 ;
479
+ memcpy (seg, temp, sizeof (XProcNumberPageSegment));
453
480
midl_user_free (temp);
454
- return ;
481
+ return seg ;
455
482
}
456
483
prev = (XProcNumberPageSegmentImpl**)&temp->nextSegment ;
457
484
temp = (XProcNumberPageSegmentImpl*)temp->nextSegment ;
458
485
}
486
+
487
+ return nullptr ;
459
488
}
460
489
461
490
void XProcNumberPageSegmentManager::Integrate ()
@@ -466,36 +495,62 @@ void XProcNumberPageSegmentManager::Integrate()
466
495
auto prev = &this ->segmentsList ;
467
496
while (temp)
468
497
{
469
- if (temp->pageSegment == 0 )
470
- {
471
- auto leafPageAllocator = recycler->GetRecyclerLeafPageAllocator ();
472
- DListBase<PageSegment> segmentList;
473
- temp->pageSegment = (intptr_t )leafPageAllocator->AllocPageSegment (segmentList, leafPageAllocator,
474
- (void *)temp->pageAddress , XProcNumberPageSegmentImpl::PageCount, temp->committedEnd / AutoSystemInfo::PageSize);
475
- leafPageAllocator->IntegrateSegments (segmentList, 1 , XProcNumberPageSegmentImpl::PageCount);
476
-
477
- this ->integratedSegmentCount ++;
478
- }
479
-
480
- unsigned int minIntegrateSize = XProcNumberPageSegmentImpl::BlockSize;
481
- for (; temp->pageAddress + temp->blockIntegratedSize + minIntegrateSize < (unsigned int )temp->allocEndAddress ;
482
- temp->blockIntegratedSize += minIntegrateSize)
498
+ if ((uintptr_t )temp->allocEndAddress - (uintptr_t )temp->pageAddress > temp->blockIntegratedSize + XProcNumberPageSegmentImpl::BlockSize)
483
499
{
484
- TRACK_ALLOC_INFO (recycler, Js::JavascriptNumber, Recycler, 0 , (size_t )-1 );
500
+ if (temp->pageSegment == 0 )
501
+ {
502
+ auto leafPageAllocator = recycler->GetRecyclerLeafPageAllocator ();
503
+ DListBase<PageSegment> segmentList;
504
+ temp->pageSegment = (intptr_t )leafPageAllocator->AllocPageSegment (segmentList, leafPageAllocator,
505
+ (void *)temp->pageAddress , XProcNumberPageSegmentImpl::PageCount, temp->committedEnd / AutoSystemInfo::PageSize);
506
+
507
+ if (temp->pageSegment )
508
+ {
509
+ leafPageAllocator->IntegrateSegments (segmentList, 1 , XProcNumberPageSegmentImpl::PageCount);
510
+ this ->integratedSegmentCount ++;
511
+ }
512
+ }
485
513
486
- if (!recycler->IntegrateBlock <LeafBit>((char *)temp->pageAddress + temp->blockIntegratedSize ,
487
- (PageSegment*)temp->pageSegment , XProcNumberPageSegmentImpl::GetSizeCat (), sizeof (Js::JavascriptNumber)))
514
+ if (temp->pageSegment )
488
515
{
489
- Js::Throw::OutOfMemory ();
516
+ unsigned int minIntegrateSize = XProcNumberPageSegmentImpl::BlockSize;
517
+ for (; temp->pageAddress + temp->blockIntegratedSize + minIntegrateSize < (unsigned int )temp->allocEndAddress ;
518
+ temp->blockIntegratedSize += minIntegrateSize)
519
+ {
520
+ TRACK_ALLOC_INFO (recycler, Js::JavascriptNumber, Recycler, 0 , (size_t )-1 );
521
+
522
+ if (!recycler->IntegrateBlock <LeafBit>((char *)temp->pageAddress + temp->blockIntegratedSize ,
523
+ (PageSegment*)temp->pageSegment , XProcNumberPageSegmentImpl::sizeCat, sizeof (Js::JavascriptNumber)))
524
+ {
525
+ Js::Throw::OutOfMemory ();
526
+ }
527
+ }
528
+
529
+ if ((uintptr_t )temp->allocEndAddress + XProcNumberPageSegmentImpl::sizeCat
530
+ > (uintptr_t )temp->pageAddress + XProcNumberPageSegmentImpl::PageCount*AutoSystemInfo::PageSize)
531
+ {
532
+ *prev = (XProcNumberPageSegmentImpl*)temp->nextSegment ;
533
+ midl_user_free (temp);
534
+ temp = *prev;
535
+ continue ;
536
+ }
490
537
}
491
538
}
492
539
493
- *prev = (XProcNumberPageSegmentImpl*)temp->nextSegment ;
494
- midl_user_free (temp);
495
- temp = *prev;
540
+ temp = (XProcNumberPageSegmentImpl*)temp->nextSegment ;
496
541
}
497
542
}
498
543
544
+ XProcNumberPageSegmentManager::XProcNumberPageSegmentManager (Recycler* recycler)
545
+ :segmentsList(nullptr ), recycler(recycler), integratedSegmentCount(0 )
546
+ {
547
+ #ifdef RECYCLER_MEMORY_VERIFY
548
+ XProcNumberPageSegmentImpl::Initialize (recycler->VerifyEnabled () == TRUE , recycler->GetVerifyPad ());
549
+ #else
550
+ XProcNumberPageSegmentImpl::Initialize (false , 0 );
551
+ #endif
552
+ }
553
+
499
554
XProcNumberPageSegmentManager::~XProcNumberPageSegmentManager ()
500
555
{
501
556
auto temp = segmentsList;
@@ -505,4 +560,5 @@ XProcNumberPageSegmentManager::~XProcNumberPageSegmentManager()
505
560
midl_user_free (temp);
506
561
temp = (XProcNumberPageSegmentImpl*)next;
507
562
}
508
- }
563
+ }
564
+ #endif
0 commit comments