summaryrefslogtreecommitdiffstats
path: root/Source/JavaScriptCore/interpreter
diff options
context:
space:
mode:
authorBen Murdoch <benm@google.com>2011-06-02 12:07:03 +0100
committerBen Murdoch <benm@google.com>2011-06-10 10:47:21 +0100
commit2daae5fd11344eaa88a0d92b0f6d65f8d2255c00 (patch)
treee4964fbd1cb70599f7718ff03e50ea1dab33890b /Source/JavaScriptCore/interpreter
parent87bdf0060a247bfbe668342b87e0874182e0ffa9 (diff)
downloadexternal_webkit-2daae5fd11344eaa88a0d92b0f6d65f8d2255c00.zip
external_webkit-2daae5fd11344eaa88a0d92b0f6d65f8d2255c00.tar.gz
external_webkit-2daae5fd11344eaa88a0d92b0f6d65f8d2255c00.tar.bz2
Merge WebKit at r84325: Initial merge by git.
Change-Id: Ic1a909300ecc0a13ddc6b4e784371d2ac6e3d59b
Diffstat (limited to 'Source/JavaScriptCore/interpreter')
-rw-r--r--Source/JavaScriptCore/interpreter/Interpreter.cpp124
-rw-r--r--Source/JavaScriptCore/interpreter/RegisterFile.cpp21
-rw-r--r--Source/JavaScriptCore/interpreter/RegisterFile.h14
3 files changed, 75 insertions, 84 deletions
diff --git a/Source/JavaScriptCore/interpreter/Interpreter.cpp b/Source/JavaScriptCore/interpreter/Interpreter.cpp
index 6021279..4a6ffb6 100644
--- a/Source/JavaScriptCore/interpreter/Interpreter.cpp
+++ b/Source/JavaScriptCore/interpreter/Interpreter.cpp
@@ -164,7 +164,7 @@ NEVER_INLINE bool Interpreter::resolveGlobal(CallFrame* callFrame, Instruction*
JSGlobalObject* globalObject = codeBlock->globalObject();
ASSERT(globalObject->isGlobalObject());
int property = vPC[2].u.operand;
- Structure* structure = vPC[3].u.structure;
+ Structure* structure = vPC[3].u.structure.get();
int offset = vPC[4].u.operand;
if (structure == globalObject->structure()) {
@@ -177,10 +177,7 @@ NEVER_INLINE bool Interpreter::resolveGlobal(CallFrame* callFrame, Instruction*
if (globalObject->getPropertySlot(callFrame, ident, slot)) {
JSValue result = slot.getValue(callFrame, ident);
if (slot.isCacheableValue() && !globalObject->structure()->isUncacheableDictionary() && slot.slotBase() == globalObject) {
- if (vPC[3].u.structure)
- vPC[3].u.structure->deref();
- globalObject->structure()->ref();
- vPC[3] = globalObject->structure();
+ vPC[3].u.structure.set(callFrame->globalData(), codeBlock->ownerExecutable(), globalObject->structure());
vPC[4] = slot.cachedOffset();
callFrame->uncheckedR(dst) = JSValue(result);
return true;
@@ -204,7 +201,7 @@ NEVER_INLINE bool Interpreter::resolveGlobalDynamic(CallFrame* callFrame, Instru
JSGlobalObject* globalObject = codeBlock->globalObject();
ASSERT(globalObject->isGlobalObject());
int property = vPC[2].u.operand;
- Structure* structure = vPC[3].u.structure;
+ Structure* structure = vPC[3].u.structure.get();
int offset = vPC[4].u.operand;
int skip = vPC[5].u.operand;
@@ -255,10 +252,7 @@ NEVER_INLINE bool Interpreter::resolveGlobalDynamic(CallFrame* callFrame, Instru
if (globalObject->getPropertySlot(callFrame, ident, slot)) {
JSValue result = slot.getValue(callFrame, ident);
if (slot.isCacheableValue() && !globalObject->structure()->isUncacheableDictionary() && slot.slotBase() == globalObject) {
- if (vPC[3].u.structure)
- vPC[3].u.structure->deref();
- globalObject->structure()->ref();
- vPC[3] = globalObject->structure();
+ vPC[3].u.structure.set(callFrame->globalData(), codeBlock->ownerExecutable(), globalObject->structure());
vPC[4] = slot.cachedOffset();
ASSERT(result);
callFrame->uncheckedR(dst) = JSValue(result);
@@ -620,7 +614,7 @@ static void appendSourceToError(CallFrame* callFrame, ErrorInstance* exception,
return;
JSGlobalData* globalData = &callFrame->globalData();
- JSValue jsMessage = exception->getDirect(globalData->propertyNames->message);
+ JSValue jsMessage = exception->getDirect(*globalData, globalData->propertyNames->message);
if (!jsMessage || !jsMessage.isString())
return;
@@ -994,9 +988,10 @@ CallFrameClosure Interpreter::prepareForRepeatCall(FunctionExecutable* FunctionE
}
CallFrame* newCallFrame = CallFrame::create(oldEnd);
+ // We initialise |this| unnecessarily here for the sake of code clarity
size_t dst = 0;
for (int i = 0; i < argc; ++i)
- newCallFrame->uncheckedR(++dst) = jsUndefined();
+ newCallFrame->uncheckedR(dst++) = jsUndefined();
JSObject* error = FunctionExecutable->compileForCall(callFrame, scopeChain);
if (error) {
@@ -1225,11 +1220,11 @@ NEVER_INLINE void Interpreter::tryCachePutByID(CallFrame* callFrame, CodeBlock*
}
// Cache miss: record Structure to compare against next time.
- Structure* lastStructure = vPC[4].u.structure;
+ Structure* lastStructure = vPC[4].u.structure.get();
if (structure != lastStructure) {
// First miss: record Structure to compare against next time.
if (!lastStructure) {
- vPC[4] = structure;
+ vPC[4].u.structure.set(callFrame->globalData(), codeBlock->ownerExecutable(), structure);
return;
}
@@ -1255,24 +1250,23 @@ NEVER_INLINE void Interpreter::tryCachePutByID(CallFrame* callFrame, CodeBlock*
// put_by_id_transition checks the prototype chain for setters.
normalizePrototypeChain(callFrame, baseCell);
-
+ JSCell* owner = codeBlock->ownerExecutable();
+ JSGlobalData& globalData = callFrame->globalData();
vPC[0] = getOpcode(op_put_by_id_transition);
- vPC[4] = structure->previousID();
- vPC[5] = structure;
- vPC[6] = structure->prototypeChain(callFrame);
+ vPC[4].u.structure.set(globalData, owner, structure->previousID());
+ vPC[5].u.structure.set(globalData, owner, structure);
+ vPC[6].u.structureChain.set(callFrame->globalData(), codeBlock->ownerExecutable(), structure->prototypeChain(callFrame));
+ ASSERT(vPC[6].u.structureChain);
vPC[7] = slot.cachedOffset();
- codeBlock->refStructures(vPC);
return;
}
vPC[0] = getOpcode(op_put_by_id_replace);
vPC[5] = slot.cachedOffset();
- codeBlock->refStructures(vPC);
}
-NEVER_INLINE void Interpreter::uncachePutByID(CodeBlock* codeBlock, Instruction* vPC)
+NEVER_INLINE void Interpreter::uncachePutByID(CodeBlock*, Instruction* vPC)
{
- codeBlock->derefStructures(vPC);
vPC[0] = getOpcode(op_put_by_id);
vPC[4] = 0;
}
@@ -1314,11 +1308,11 @@ NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock*
}
// Cache miss
- Structure* lastStructure = vPC[4].u.structure;
+ Structure* lastStructure = vPC[4].u.structure.get();
if (structure != lastStructure) {
// First miss: record Structure to compare against next time.
if (!lastStructure) {
- vPC[4] = structure;
+ vPC[4].u.structure.set(callFrame->globalData(), codeBlock->ownerExecutable(), structure);
return;
}
@@ -1344,8 +1338,6 @@ NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock*
vPC[5] = slot.cachedOffset();
break;
}
-
- codeBlock->refStructures(vPC);
return;
}
@@ -1364,7 +1356,7 @@ NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock*
// should not be treated as a dictionary.
if (baseObject->structure()->isDictionary()) {
baseObject->flattenDictionaryObject(callFrame->globalData());
- offset = baseObject->structure()->get(propertyName);
+ offset = baseObject->structure()->get(callFrame->globalData(), propertyName);
}
ASSERT(!baseObject->structure()->isUncacheableDictionary());
@@ -1383,9 +1375,7 @@ NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock*
vPC[6] = offset;
break;
}
- vPC[5] = baseObject->structure();
-
- codeBlock->refStructures(vPC);
+ vPC[5].u.structure.set(callFrame->globalData(), codeBlock->ownerExecutable(), baseObject->structure());
return;
}
@@ -1411,15 +1401,13 @@ NEVER_INLINE void Interpreter::tryCacheGetByID(CallFrame* callFrame, CodeBlock*
vPC[7] = offset;
break;
}
- vPC[4] = structure;
- vPC[5] = structure->prototypeChain(callFrame);
+ vPC[4].u.structure.set(callFrame->globalData(), codeBlock->ownerExecutable(), structure);
+ vPC[5].u.structureChain.set(callFrame->globalData(), codeBlock->ownerExecutable(), structure->prototypeChain(callFrame));
vPC[6] = count;
- codeBlock->refStructures(vPC);
}
-NEVER_INLINE void Interpreter::uncacheGetByID(CodeBlock* codeBlock, Instruction* vPC)
+NEVER_INLINE void Interpreter::uncacheGetByID(CodeBlock*, Instruction* vPC)
{
- codeBlock->derefStructures(vPC);
vPC[0] = getOpcode(op_get_by_id);
vPC[4] = 0;
}
@@ -2528,7 +2516,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
if (LIKELY(baseValue.isCell())) {
JSCell* baseCell = baseValue.asCell();
- Structure* structure = vPC[4].u.structure;
+ Structure* structure = vPC[4].u.structure.get();
if (LIKELY(baseCell->structure() == structure)) {
ASSERT(baseCell->isObject());
@@ -2559,12 +2547,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
if (LIKELY(baseValue.isCell())) {
JSCell* baseCell = baseValue.asCell();
- Structure* structure = vPC[4].u.structure;
+ Structure* structure = vPC[4].u.structure.get();
if (LIKELY(baseCell->structure() == structure)) {
ASSERT(structure->prototypeForLookup(callFrame).isObject());
JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame));
- Structure* prototypeStructure = vPC[5].u.structure;
+ Structure* prototypeStructure = vPC[5].u.structure.get();
if (LIKELY(protoObject->structure() == prototypeStructure)) {
int dst = vPC[1].u.operand;
@@ -2598,12 +2586,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
if (LIKELY(baseValue.isCell())) {
JSCell* baseCell = baseValue.asCell();
- Structure* structure = vPC[4].u.structure;
+ Structure* structure = vPC[4].u.structure.get();
if (LIKELY(baseCell->structure() == structure)) {
ASSERT(structure->prototypeForLookup(callFrame).isObject());
JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame));
- Structure* prototypeStructure = vPC[5].u.structure;
+ Structure* prototypeStructure = vPC[5].u.structure.get();
if (LIKELY(protoObject->structure() == prototypeStructure)) {
int dst = vPC[1].u.operand;
@@ -2643,12 +2631,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
if (LIKELY(baseValue.isCell())) {
JSCell* baseCell = baseValue.asCell();
- Structure* structure = vPC[4].u.structure;
+ Structure* structure = vPC[4].u.structure.get();
if (LIKELY(baseCell->structure() == structure)) {
ASSERT(structure->prototypeForLookup(callFrame).isObject());
JSObject* protoObject = asObject(structure->prototypeForLookup(callFrame));
- Structure* prototypeStructure = vPC[5].u.structure;
+ Structure* prototypeStructure = vPC[5].u.structure.get();
if (LIKELY(protoObject->structure() == prototypeStructure)) {
int dst = vPC[1].u.operand;
@@ -2712,6 +2700,9 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
vPC += OPCODE_LENGTH(op_get_by_id_proto_list);
NEXT_INSTRUCTION();
}
+#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
+ goto *(&&skip_get_by_id_chain);
+#endif
DEFINE_OPCODE(op_get_by_id_chain) {
/* op_get_by_id_chain dst(r) base(r) property(id) structure(sID) structureChain(chain) count(n) offset(n)
@@ -2724,12 +2715,12 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
if (LIKELY(baseValue.isCell())) {
JSCell* baseCell = baseValue.asCell();
- Structure* structure = vPC[4].u.structure;
+ Structure* structure = vPC[4].u.structure.get();
if (LIKELY(baseCell->structure() == structure)) {
- RefPtr<Structure>* it = vPC[5].u.structureChain->head();
+ WriteBarrier<Structure>* it = vPC[5].u.structureChain->head();
size_t count = vPC[6].u.operand;
- RefPtr<Structure>* end = it + count;
+ WriteBarrier<Structure>* end = it + count;
while (true) {
JSObject* baseObject = asObject(baseCell->structure()->prototypeForLookup(callFrame));
@@ -2759,6 +2750,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
NEXT_INSTRUCTION();
}
#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
+ skip_get_by_id_chain:
goto *(&&skip_id_getter_self);
#endif
DEFINE_OPCODE(op_get_by_id_getter_self) {
@@ -2773,7 +2765,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
if (LIKELY(baseValue.isCell())) {
JSCell* baseCell = baseValue.asCell();
- Structure* structure = vPC[4].u.structure;
+ Structure* structure = vPC[4].u.structure.get();
if (LIKELY(baseCell->structure() == structure)) {
ASSERT(baseCell->isObject());
@@ -2816,7 +2808,7 @@ JSValue Interpreter::privateExecute(ExecutionFlag flag, RegisterFile* registerFi
if (LIKELY(baseValue.isCell())) {
JSCell* baseCell = baseValue.asCell();
- Structure* structure = vPC[4].u.structure;
+ Structure* structure = vPC[4].u.structure.get();
if (LIKELY(baseCell->structure() == structure)) {
ASSERT(baseCell->isObject());
@@ -2873,12 +2865,12 @@ skip_id_custom_self:
if (LIKELY(baseValue.isCell())) {
JSCell* baseCell = baseValue.asCell();
- Structure* structure = vPC[4].u.structure;
+ Structure* structure = vPC[4].u.structure.get();
if (LIKELY(baseCell->structure() == structure)) {
- RefPtr<Structure>* it = vPC[5].u.structureChain->head();
+ WriteBarrier<Structure>* it = vPC[5].u.structureChain->head();
size_t count = vPC[6].u.operand;
- RefPtr<Structure>* end = it + count;
+ WriteBarrier<Structure>* end = it + count;
while (true) {
JSObject* baseObject = asObject(baseCell->structure()->prototypeForLookup(callFrame));
@@ -2928,12 +2920,12 @@ skip_id_custom_self:
if (LIKELY(baseValue.isCell())) {
JSCell* baseCell = baseValue.asCell();
- Structure* structure = vPC[4].u.structure;
+ Structure* structure = vPC[4].u.structure.get();
if (LIKELY(baseCell->structure() == structure)) {
- RefPtr<Structure>* it = vPC[5].u.structureChain->head();
+ WriteBarrier<Structure>* it = vPC[5].u.structureChain->head();
size_t count = vPC[6].u.operand;
- RefPtr<Structure>* end = it + count;
+ WriteBarrier<Structure>* end = it + count;
while (true) {
JSObject* baseObject = asObject(baseCell->structure()->prototypeForLookup(callFrame));
@@ -2964,6 +2956,7 @@ skip_id_custom_self:
}
#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
skip_id_custom_chain:
+ goto *(&&skip_get_array_length);
#endif
DEFINE_OPCODE(op_get_array_length) {
/* op_get_array_length dst(r) base(r) property(id) nop(sID) nop(n) nop(n) nop(n)
@@ -2985,6 +2978,10 @@ skip_id_custom_self:
uncacheGetByID(codeBlock, vPC);
NEXT_INSTRUCTION();
}
+#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
+ skip_get_array_length:
+ goto *(&&skip_get_string_length);
+#endif
DEFINE_OPCODE(op_get_string_length) {
/* op_get_string_length dst(r) base(r) property(id) nop(sID) nop(n) nop(n) nop(n)
@@ -3005,6 +3002,10 @@ skip_id_custom_self:
uncacheGetByID(codeBlock, vPC);
NEXT_INSTRUCTION();
}
+#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
+ skip_get_string_length:
+ goto *(&&skip_put_by_id);
+#endif
DEFINE_OPCODE(op_put_by_id) {
/* put_by_id base(r) property(id) value(r) nop(n) nop(n) nop(n) nop(n) direct(b)
@@ -3038,6 +3039,9 @@ skip_id_custom_self:
vPC += OPCODE_LENGTH(op_put_by_id);
NEXT_INSTRUCTION();
}
+#if USE(GCC_COMPUTED_GOTO_WORKAROUND)
+ skip_put_by_id:
+#endif
DEFINE_OPCODE(op_put_by_id_transition) {
/* op_put_by_id_transition base(r) property(id) value(r) oldStructure(sID) newStructure(sID) structureChain(chain) offset(n) direct(b)
@@ -3054,8 +3058,8 @@ skip_id_custom_self:
if (LIKELY(baseValue.isCell())) {
JSCell* baseCell = baseValue.asCell();
- Structure* oldStructure = vPC[4].u.structure;
- Structure* newStructure = vPC[5].u.structure;
+ Structure* oldStructure = vPC[4].u.structure.get();
+ Structure* newStructure = vPC[5].u.structure.get();
if (LIKELY(baseCell->structure() == oldStructure)) {
ASSERT(baseCell->isObject());
@@ -3063,7 +3067,7 @@ skip_id_custom_self:
int direct = vPC[8].u.operand;
if (!direct) {
- RefPtr<Structure>* it = vPC[6].u.structureChain->head();
+ WriteBarrier<Structure>* it = vPC[6].u.structureChain->head();
JSValue proto = baseObject->structure()->prototypeForLookup(callFrame);
while (!proto.isNull()) {
@@ -3075,11 +3079,11 @@ skip_id_custom_self:
proto = asObject(proto)->structure()->prototypeForLookup(callFrame);
}
}
- baseObject->transitionTo(newStructure);
+ baseObject->transitionTo(*globalData, newStructure);
int value = vPC[3].u.operand;
unsigned offset = vPC[7].u.operand;
- ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(codeBlock->identifier(vPC[2].u.operand))) == offset);
+ ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(*globalData, codeBlock->identifier(vPC[2].u.operand))) == offset);
baseObject->putDirectOffset(callFrame->globalData(), offset, callFrame->r(value).jsValue());
vPC += OPCODE_LENGTH(op_put_by_id_transition);
@@ -3106,7 +3110,7 @@ skip_id_custom_self:
if (LIKELY(baseValue.isCell())) {
JSCell* baseCell = baseValue.asCell();
- Structure* structure = vPC[4].u.structure;
+ Structure* structure = vPC[4].u.structure.get();
if (LIKELY(baseCell->structure() == structure)) {
ASSERT(baseCell->isObject());
@@ -3114,7 +3118,7 @@ skip_id_custom_self:
int value = vPC[3].u.operand;
unsigned offset = vPC[5].u.operand;
- ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(codeBlock->identifier(vPC[2].u.operand))) == offset);
+ ASSERT(baseObject->offsetForLocation(baseObject->getDirectLocation(*globalData, codeBlock->identifier(vPC[2].u.operand))) == offset);
baseObject->putDirectOffset(callFrame->globalData(), offset, callFrame->r(value).jsValue());
vPC += OPCODE_LENGTH(op_put_by_id_replace);
diff --git a/Source/JavaScriptCore/interpreter/RegisterFile.cpp b/Source/JavaScriptCore/interpreter/RegisterFile.cpp
index b3a87e5..e3b34bb 100644
--- a/Source/JavaScriptCore/interpreter/RegisterFile.cpp
+++ b/Source/JavaScriptCore/interpreter/RegisterFile.cpp
@@ -29,7 +29,7 @@
#include "config.h"
#include "RegisterFile.h"
-#include "ConservativeSet.h"
+#include "ConservativeRoots.h"
#include "Interpreter.h"
#include "JSGlobalData.h"
#include "JSGlobalObject.h"
@@ -72,24 +72,7 @@ void RegisterFile::releaseExcessCapacity()
void RegisterFile::setGlobalObject(JSGlobalObject* globalObject)
{
- m_globalObject.set(globalObject->globalData(), globalObject, RegisterFile::globalObjectCollectedNotifier());
-}
-
-class GlobalObjectNotifier : public Finalizer {
-public:
- void finalize(Handle<Unknown> value, void*)
- {
- JSGlobalObject* globalObject = asGlobalObject(value.get());
- globalObject->globalData().interpreter->registerFile().setNumGlobals(0);
- }
-};
-
-Finalizer* RegisterFile::globalObjectCollectedNotifier()
-{
- // This will leak alas, but we only create one of them, and it doesn't
- // take up any significant amount of space.
- static GlobalObjectNotifier* notifier = new GlobalObjectNotifier;
- return notifier;
+ m_globalObject.set(globalObject->globalData(), globalObject, &m_globalObjectOwner, this);
}
JSGlobalObject* RegisterFile::globalObject()
diff --git a/Source/JavaScriptCore/interpreter/RegisterFile.h b/Source/JavaScriptCore/interpreter/RegisterFile.h
index 4d04085..f59c13a 100644
--- a/Source/JavaScriptCore/interpreter/RegisterFile.h
+++ b/Source/JavaScriptCore/interpreter/RegisterFile.h
@@ -32,7 +32,7 @@
#include "Heap.h"
#include "ExecutableAllocator.h"
#include "Register.h"
-#include "WeakGCPtr.h"
+#include "Weak.h"
#include <stdio.h>
#include <wtf/Noncopyable.h>
#include <wtf/PageReservation.h>
@@ -135,8 +135,6 @@ namespace JSC {
static size_t committedByteCount();
static void initializeThreading();
- static Finalizer* globalObjectCollectedNotifier();
-
Register* const * addressOfEnd() const
{
return &m_end;
@@ -154,7 +152,13 @@ namespace JSC {
Register* m_commitEnd;
PageReservation m_reservation;
- WeakGCPtr<JSGlobalObject> m_globalObject; // The global object whose vars are currently stored in the register file.
+ Weak<JSGlobalObject> m_globalObject; // The global object whose vars are currently stored in the register file.
+ class GlobalObjectOwner : public WeakHandleOwner {
+ virtual void finalize(Handle<Unknown>, void* context)
+ {
+ static_cast<RegisterFile*>(context)->setNumGlobals(0);
+ }
+ } m_globalObjectOwner;
};
inline RegisterFile::RegisterFile(JSGlobalData& globalData, size_t capacity, size_t maxGlobals)
@@ -163,7 +167,7 @@ namespace JSC {
, m_start(0)
, m_end(0)
, m_max(0)
- , m_globalObject(globalData, RegisterFile::globalObjectCollectedNotifier())
+ , m_globalObject(globalData, 0, &m_globalObjectOwner, this)
{
ASSERT(maxGlobals && isPageAligned(maxGlobals));
ASSERT(capacity && isPageAligned(capacity));