Modified: trunk/Source/_javascript_Core/ftl/FTLAbstractHeapRepository.h (209111 => 209112)
--- trunk/Source/_javascript_Core/ftl/FTLAbstractHeapRepository.h 2016-11-30 03:05:55 UTC (rev 209111)
+++ trunk/Source/_javascript_Core/ftl/FTLAbstractHeapRepository.h 2016-11-30 03:09:10 UTC (rev 209112)
@@ -67,6 +67,8 @@
macro(JSFunction_executable, JSFunction::offsetOfExecutable()) \
macro(JSFunction_scope, JSFunction::offsetOfScopeChain()) \
macro(JSFunction_rareData, JSFunction::offsetOfRareData()) \
+ macro(FunctionRareData_allocator, FunctionRareData::offsetOfObjectAllocationProfile() + ObjectAllocationProfile::offsetOfAllocator()) \
+ macro(FunctionRareData_structure, FunctionRareData::offsetOfObjectAllocationProfile() + ObjectAllocationProfile::offsetOfStructure()) \
macro(JSObject_butterfly, JSObject::butterflyOffset()) \
macro(JSPropertyNameEnumerator_cachedInlineCapacity, JSPropertyNameEnumerator::cachedInlineCapacityOffset()) \
macro(JSPropertyNameEnumerator_cachedPropertyNamesVector, JSPropertyNameEnumerator::cachedPropertyNamesVectorOffset()) \
@@ -107,6 +109,8 @@
macro(Structure_globalObject, Structure::globalObjectOffset()) \
macro(Structure_prototype, Structure::prototypeOffset()) \
macro(Structure_structureID, Structure::structureIDOffset()) \
+ macro(Structure_inlineCapacity, Structure::inlineCapacityOffset()) \
+ macro(Structure_initializationBlob, Structure::indexingTypeIncludingHistoryOffset()) \
macro(JSMap_hashMapImpl, JSMap::offsetOfHashMapImpl()) \
macro(JSSet_hashMapImpl, JSSet::offsetOfHashMapImpl()) \
macro(HashMapImpl_capacity, HashMapImpl<HashMapBucket<HashMapBucketDataKey>>::offsetOfCapacity()) \
Modified: trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp (209111 => 209112)
--- trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2016-11-30 03:05:55 UTC (rev 209111)
+++ trunk/Source/_javascript_Core/ftl/FTLLowerDFGToB3.cpp 2016-11-30 03:09:10 UTC (rev 209112)
@@ -1073,6 +1073,9 @@
case CallDOMGetter:
compileCallDOMGetter();
break;
+ case CreateThis:
+ compileCreateThis();
+ break;
case PhantomLocal:
case LoopHint:
@@ -4855,7 +4858,7 @@
DFG_ASSERT(m_graph, m_node, allocator);
LValue result = allocateCell(
- m_out.constIntPtr(allocator), vm().stringStructure.get(), slowPath);
+ m_out.constIntPtr(allocator), m_out.constIntPtr(vm().stringStructure.get()), slowPath);
m_out.storePtr(m_out.intPtrZero, result, m_heaps.JSString_value);
for (unsigned i = 0; i < numKids; ++i)
@@ -8145,7 +8148,7 @@
m_out.store32(vectorLength, fastButterflyValue, m_heaps.Butterfly_vectorLength);
LValue fastObjectValue = allocateObject(
- m_out.constIntPtr(cellAllocator), structure, fastButterflyValue, slowPath);
+ m_out.constIntPtr(cellAllocator), m_out.constIntPtr(structure), fastButterflyValue, slowPath);
ValueFromBlock fastObject = m_out.anchor(fastObjectValue);
ValueFromBlock fastButterfly = m_out.anchor(fastButterflyValue);
@@ -9492,6 +9495,40 @@
patchpoint->effects = Effects::forCall();
setJSValue(patchpoint);
}
+
+ void compileCreateThis()
+ {
+ LValue callee = lowCell(m_node->child1());
+
+ LBasicBlock isFunctionBlock = m_out.newBlock();
+ LBasicBlock hasRareData = m_out.newBlock();
+ LBasicBlock slowPath = m_out.newBlock();
+ LBasicBlock continuation = m_out.newBlock();
+
+ m_out.branch(isFunction(callee, provenType(m_node->child1())), usually(isFunctionBlock), rarely(slowPath));
+
+ LBasicBlock lastNext = m_out.appendTo(isFunctionBlock, hasRareData);
+ LValue rareData = m_out.loadPtr(callee, m_heaps.JSFunction_rareData);
+ m_out.branch(m_out.isZero64(rareData), rarely(slowPath), usually(hasRareData));
+
+ m_out.appendTo(hasRareData, slowPath);
+ LValue allocator = m_out.loadPtr(rareData, m_heaps.FunctionRareData_allocator);
+ LValue structure = m_out.loadPtr(rareData, m_heaps.FunctionRareData_structure);
+ LValue butterfly = m_out.constIntPtr(0);
+ ValueFromBlock fastResult = m_out.anchor(allocateObject(allocator, structure, butterfly, slowPath));
+ m_out.jump(continuation);
+
+ m_out.appendTo(slowPath, continuation);
+ ValueFromBlock slowResult = m_out.anchor(vmCall(
+ Int64, m_out.operation(operationCreateThis), m_callFrame, callee, m_out.constInt32(m_node->inlineCapacity())));
+ m_out.jump(continuation);
+
+ m_out.appendTo(continuation, lastNext);
+ LValue result = m_out.phi(Int64, fastResult, slowResult);
+
+ mutatorFence();
+ setJSValue(result);
+ }
void compareEqObjectOrOtherToObject(Edge leftChild, Edge rightChild)
{
@@ -9912,16 +9949,24 @@
m_out.appendTo(continuation, lastNext);
return patchpoint;
}
-
- void storeStructure(LValue object, Structure* structure)
+
+ void storeStructure(LValue object, LValue structure)
{
- m_out.store32(m_out.constInt32(structure->id()), object, m_heaps.JSCell_structureID);
- m_out.store32(
- m_out.constInt32(structure->objectInitializationBlob()),
- object, m_heaps.JSCell_usefulBytes);
+ LValue id;
+ LValue blob;
+ if (structure->hasIntPtr()) {
+ Structure* actualStructure = bitwise_cast<Structure*>(structure->asIntPtr());
+ id = m_out.constInt32(actualStructure->id());
+ blob = m_out.constInt32(actualStructure->objectInitializationBlob());
+ } else {
+ id = m_out.load32(structure, m_heaps.Structure_structureID);
+ blob = m_out.load32(structure, m_heaps.Structure_initializationBlob);
+ }
+ m_out.store32(id, object, m_heaps.JSCell_structureID);
+ m_out.store32(blob, object, m_heaps.JSCell_usefulBytes);
}
- LValue allocateCell(LValue allocator, Structure* structure, LBasicBlock slowPath)
+ LValue allocateCell(LValue allocator, LValue structure, LBasicBlock slowPath)
{
LValue result = allocateHeapCell(allocator, slowPath);
storeStructure(result, structure);
@@ -9929,14 +9974,22 @@
}
LValue allocateObject(
- LValue allocator, Structure* structure, LValue butterfly, LBasicBlock slowPath)
+ LValue allocator, LValue structure, LValue butterfly, LBasicBlock slowPath)
{
LValue result = allocateCell(allocator, structure, slowPath);
if (useGCFences()) {
+ LValue start = m_out.constInt32(JSFinalObject::offsetOfInlineStorage() / 8);
+ LValue end;
+ if (structure->hasIntPtr()) {
+ Structure* actualStructure = bitwise_cast<Structure*>(structure->asIntPtr());
+ end = m_out.constInt32(JSFinalObject::offsetOfInlineStorage() / 8 + actualStructure->inlineCapacity());
+ } else
+ end = m_out.add(start, m_out.load8ZeroExt32(structure, m_heaps.Structure_inlineCapacity));
+
splatWords(
result,
- m_out.constInt32(JSFinalObject::offsetOfInlineStorage() / 8),
- m_out.constInt32(JSFinalObject::offsetOfInlineStorage() / 8 + structure->inlineCapacity()),
+ start,
+ end,
m_out.int64Zero,
m_heaps.properties.atAnyNumber());
}
@@ -9949,7 +10002,7 @@
size_t size, Structure* structure, LValue butterfly, LBasicBlock slowPath)
{
MarkedAllocator* allocator = vm().heap.allocatorForObjectOfType<ClassType>(size);
- return allocateObject(m_out.constIntPtr(allocator), structure, butterfly, slowPath);
+ return allocateObject(m_out.constIntPtr(allocator), m_out.constIntPtr(structure), butterfly, slowPath);
}
template<typename ClassType>
@@ -10013,7 +10066,7 @@
{
LValue allocator = allocatorForSize(
vm().heap.subspaceForObjectOfType<ClassType>(), size, slowPath);
- return allocateObject(allocator, structure, butterfly, slowPath);
+ return allocateObject(allocator, m_out.constIntPtr(structure), butterfly, slowPath);
}
template<typename ClassType>
@@ -10022,7 +10075,7 @@
{
LValue allocator = allocatorForSize(
vm().heap.subspaceForObjectOfType<ClassType>(), size, slowPath);
- return allocateCell(allocator, structure, slowPath);
+ return allocateCell(allocator, m_out.constIntPtr(structure), slowPath);
}
LValue allocateObject(Structure* structure)
@@ -10040,7 +10093,7 @@
LBasicBlock lastNext = m_out.insertNewBlocksBefore(slowPath);
ValueFromBlock fastResult = m_out.anchor(allocateObject(
- m_out.constIntPtr(allocator), structure, m_out.intPtrZero, slowPath));
+ m_out.constIntPtr(allocator), m_out.constIntPtr(structure), m_out.intPtrZero, slowPath));
m_out.jump(continuation);