<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[167641] trunk/Source/JavaScriptCore</title>
</head>
<body>
<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; }
#msg dl a { font-weight: bold}
#msg dl a:link { color:#fc3; }
#msg dl a:active { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/167641">167641</a></dd>
<dt>Author</dt> <dd>mhahnenberg@apple.com</dd>
<dt>Date</dt> <dd>2014-04-21 18:37:34 -0700 (Mon, 21 Apr 2014)</dd>
</dl>
<h3>Log Message</h3>
<pre>Arguments objects shouldn't need a destructor
https://bugs.webkit.org/show_bug.cgi?id=131899
Reviewed by Oliver Hunt.
This patch rids Arguments objects of their destructors. It does this by
switching their backing stores to use CopiedSpace rather than malloc memory.
* dfg/DFGSpeculativeJIT.cpp:
(JSC::DFG::SpeculativeJIT::emitAllocateArguments): Fix the code emitted for inline
Arguments allocation so that it only emits an extra write for strict mode code rather
than unconditionally.
* heap/CopyToken.h: New CopyTokens for the two different types of Arguments backing stores.
* runtime/Arguments.cpp:
(JSC::Arguments::visitChildren): We need to tell the collector to copy the back stores now.
(JSC::Arguments::copyBackingStore): Do the actual copying of the backing stores.
(JSC::Arguments::deletePropertyByIndex): Update all the accesses to SlowArgumentData and m_registerArray.
(JSC::Arguments::deleteProperty):
(JSC::Arguments::defineOwnProperty):
(JSC::Arguments::allocateRegisterArray):
(JSC::Arguments::tearOff):
(JSC::Arguments::destroy): Deleted. We don't need the destructor any more.
* runtime/Arguments.h:
(JSC::Arguments::registerArraySizeInBytes):
(JSC::Arguments::SlowArgumentData::SlowArgumentData): Switch SlowArgumentData to being allocated
in CopiedSpace. Now the SlowArgumentData and its backing store are a single contiguous CopiedSpace
allocation.
(JSC::Arguments::SlowArgumentData::slowArguments):
(JSC::Arguments::SlowArgumentData::bytecodeToMachineCaptureOffset):
(JSC::Arguments::SlowArgumentData::setBytecodeToMachineCaptureOffset):
(JSC::Arguments::SlowArgumentData::sizeForNumArguments):
(JSC::Arguments::Arguments):
(JSC::Arguments::allocateSlowArguments):
(JSC::Arguments::tryDeleteArgument):
(JSC::Arguments::isDeletedArgument):
(JSC::Arguments::isArgument):
(JSC::Arguments::argument):
(JSC::Arguments::finishCreation):
* runtime/SymbolTable.h:</pre>
<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp">trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreheapCopyTokenh">trunk/Source/JavaScriptCore/heap/CopyToken.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeArgumentscpp">trunk/Source/JavaScriptCore/runtime/Arguments.cpp</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeArgumentsh">trunk/Source/JavaScriptCore/runtime/Arguments.h</a></li>
<li><a href="#trunkSourceJavaScriptCoreruntimeSymbolTableh">trunk/Source/JavaScriptCore/runtime/SymbolTable.h</a></li>
</ul>
</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (167640 => 167641)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2014-04-22 01:34:46 UTC (rev 167640)
+++ trunk/Source/JavaScriptCore/ChangeLog        2014-04-22 01:37:34 UTC (rev 167641)
</span><span class="lines">@@ -1,3 +1,45 @@
</span><ins>+2014-04-21 Mark Hahnenberg <mhahnenberg@apple.com>
+
+ Arguments objects shouldn't need a destructor
+ https://bugs.webkit.org/show_bug.cgi?id=131899
+
+ Reviewed by Oliver Hunt.
+
+ This patch rids Arguments objects of their destructors. It does this by
+ switching their backing stores to use CopiedSpace rather than malloc memory.
+
+ * dfg/DFGSpeculativeJIT.cpp:
+ (JSC::DFG::SpeculativeJIT::emitAllocateArguments): Fix the code emitted for inline
+ Arguments allocation so that it only emits an extra write for strict mode code rather
+ than unconditionally.
+ * heap/CopyToken.h: New CopyTokens for the two different types of Arguments backing stores.
+ * runtime/Arguments.cpp:
+ (JSC::Arguments::visitChildren): We need to tell the collector to copy the back stores now.
+ (JSC::Arguments::copyBackingStore): Do the actual copying of the backing stores.
+ (JSC::Arguments::deletePropertyByIndex): Update all the accesses to SlowArgumentData and m_registerArray.
+ (JSC::Arguments::deleteProperty):
+ (JSC::Arguments::defineOwnProperty):
+ (JSC::Arguments::allocateRegisterArray):
+ (JSC::Arguments::tearOff):
+ (JSC::Arguments::destroy): Deleted. We don't need the destructor any more.
+ * runtime/Arguments.h:
+ (JSC::Arguments::registerArraySizeInBytes):
+ (JSC::Arguments::SlowArgumentData::SlowArgumentData): Switch SlowArgumentData to being allocated
+ in CopiedSpace. Now the SlowArgumentData and its backing store are a single contiguous CopiedSpace
+ allocation.
+ (JSC::Arguments::SlowArgumentData::slowArguments):
+ (JSC::Arguments::SlowArgumentData::bytecodeToMachineCaptureOffset):
+ (JSC::Arguments::SlowArgumentData::setBytecodeToMachineCaptureOffset):
+ (JSC::Arguments::SlowArgumentData::sizeForNumArguments):
+ (JSC::Arguments::Arguments):
+ (JSC::Arguments::allocateSlowArguments):
+ (JSC::Arguments::tryDeleteArgument):
+ (JSC::Arguments::isDeletedArgument):
+ (JSC::Arguments::isArgument):
+ (JSC::Arguments::argument):
+ (JSC::Arguments::finishCreation):
+ * runtime/SymbolTable.h:
+
</ins><span class="cx"> 2014-04-21 Eric Carlson <eric.carlson@apple.com>
</span><span class="cx">
</span><span class="cx"> [Mac] implement WebKitDataCue
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoredfgDFGSpeculativeJITcpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp (167640 => 167641)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2014-04-22 01:34:46 UTC (rev 167640)
+++ trunk/Source/JavaScriptCore/dfg/DFGSpeculativeJIT.cpp        2014-04-22 01:37:34 UTC (rev 167641)
</span><span class="lines">@@ -118,8 +118,8 @@
</span><span class="cx"> m_jit.store32(scratchGPR1, MacroAssembler::Address(resultGPR, Arguments::offsetOfNumArguments()));
</span><span class="cx">
</span><span class="cx"> m_jit.store32(TrustedImm32(0), MacroAssembler::Address(resultGPR, Arguments::offsetOfOverrodeLength()));
</span><del>- m_jit.store8(TrustedImm32(m_jit.isStrictModeFor(m_currentNode->origin.semantic)),
- MacroAssembler::Address(resultGPR, Arguments::offsetOfIsStrictMode()));
</del><ins>+ if (m_jit.isStrictModeFor(m_currentNode->origin.semantic))
+ m_jit.store8(TrustedImm32(1), MacroAssembler::Address(resultGPR, Arguments::offsetOfIsStrictMode()));
</ins><span class="cx">
</span><span class="cx"> m_jit.storePtr(GPRInfo::callFrameRegister, MacroAssembler::Address(resultGPR, Arguments::offsetOfRegisters()));
</span><span class="cx"> m_jit.storePtr(TrustedImmPtr(0), MacroAssembler::Address(resultGPR, Arguments::offsetOfRegisterArray()));
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreheapCopyTokenh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/heap/CopyToken.h (167640 => 167641)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/heap/CopyToken.h        2014-04-22 01:34:46 UTC (rev 167640)
+++ trunk/Source/JavaScriptCore/heap/CopyToken.h        2014-04-22 01:37:34 UTC (rev 167641)
</span><span class="lines">@@ -31,7 +31,9 @@
</span><span class="cx"> enum CopyToken {
</span><span class="cx"> ButterflyCopyToken,
</span><span class="cx"> TypedArrayVectorCopyToken,
</span><del>- MapBackingStoreCopyToken
</del><ins>+ MapBackingStoreCopyToken,
+ ArgumentsRegisterArrayCopyToken,
+ ArgumentsSlowArgumentDataCopyToken
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> } // namespace JSC
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeArgumentscpp"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Arguments.cpp (167640 => 167641)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Arguments.cpp        2014-04-22 01:34:46 UTC (rev 167640)
+++ trunk/Source/JavaScriptCore/runtime/Arguments.cpp        2014-04-22 01:37:34 UTC (rev 167641)
</span><span class="lines">@@ -25,6 +25,7 @@
</span><span class="cx"> #include "config.h"
</span><span class="cx"> #include "Arguments.h"
</span><span class="cx">
</span><ins>+#include "CopyVisitorInlines.h"
</ins><span class="cx"> #include "JSActivation.h"
</span><span class="cx"> #include "JSArgumentsIterator.h"
</span><span class="cx"> #include "JSFunction.h"
</span><span class="lines">@@ -35,6 +36,8 @@
</span><span class="cx">
</span><span class="cx"> namespace JSC {
</span><span class="cx">
</span><ins>+STATIC_ASSERT_IS_TRIVIALLY_DESTRUCTIBLE(Arguments);
+
</ins><span class="cx"> const ClassInfo Arguments::s_info = { "Arguments", &Base::s_info, 0, 0, CREATE_METHOD_TABLE(Arguments) };
</span><span class="cx">
</span><span class="cx"> void Arguments::visitChildren(JSCell* cell, SlotVisitor& visitor)
</span><span class="lines">@@ -45,18 +48,62 @@
</span><span class="cx"> ASSERT(thisObject->structure()->typeInfo().overridesVisitChildren());
</span><span class="cx"> JSObject::visitChildren(thisObject, visitor);
</span><span class="cx">
</span><del>- if (thisObject->m_registerArray)
</del><ins>+ if (thisObject->m_registerArray) {
+ visitor.copyLater(thisObject, ArgumentsRegisterArrayCopyToken,
+ thisObject->m_registerArray.get(), thisObject->registerArraySizeInBytes());
</ins><span class="cx"> visitor.appendValues(thisObject->m_registerArray.get(), thisObject->m_numArguments);
</span><ins>+ }
+ if (thisObject->m_slowArgumentData) {
+ visitor.copyLater(thisObject, ArgumentsSlowArgumentDataCopyToken,
+ thisObject->m_slowArgumentData.get(), SlowArgumentData::sizeForNumArguments(thisObject->m_numArguments));
+ }
</ins><span class="cx"> visitor.append(&thisObject->m_callee);
</span><span class="cx"> visitor.append(&thisObject->m_activation);
</span><span class="cx"> }
</span><ins>+
+void Arguments::copyBackingStore(JSCell* cell, CopyVisitor& visitor, CopyToken token)
+{
+ Arguments* thisObject = jsCast<Arguments*>(cell);
+ ASSERT_GC_OBJECT_INHERITS(thisObject, info());
</ins><span class="cx">
</span><del>-static EncodedJSValue JSC_HOST_CALL argumentsFuncIterator(ExecState*);
</del><span class="cx">
</span><del>-void Arguments::destroy(JSCell* cell)
-{
- static_cast<Arguments*>(cell)->Arguments::~Arguments();
</del><ins>+ switch (token) {
+ case ArgumentsRegisterArrayCopyToken: {
+ WriteBarrier<Unknown>* registerArray = thisObject->m_registerArray.get();
+ if (!registerArray)
+ return;
+
+ if (visitor.checkIfShouldCopy(registerArray)) {
+ size_t bytes = thisObject->registerArraySizeInBytes();
+ WriteBarrier<Unknown>* newRegisterArray = static_cast<WriteBarrier<Unknown>*>(visitor.allocateNewSpace(bytes));
+ memcpy(newRegisterArray, registerArray, bytes);
+ thisObject->m_registerArray.setWithoutWriteBarrier(newRegisterArray);
+ visitor.didCopy(registerArray, bytes);
+ }
+ return;
+ }
+
+ case ArgumentsSlowArgumentDataCopyToken: {
+ SlowArgumentData* slowArgumentData = thisObject->m_slowArgumentData.get();
+ if (!slowArgumentData)
+ return;
+
+ if (visitor.checkIfShouldCopy(slowArgumentData)) {
+ size_t bytes = SlowArgumentData::sizeForNumArguments(thisObject->m_numArguments);
+ SlowArgumentData* newSlowArgumentData = static_cast<SlowArgumentData*>(visitor.allocateNewSpace(bytes));
+ memcpy(newSlowArgumentData, slowArgumentData, bytes);
+ thisObject->m_slowArgumentData.setWithoutWriteBarrier(newSlowArgumentData);
+ visitor.didCopy(slowArgumentData, bytes);
+ }
+ return;
+ }
+
+ default:
+ return;
+ }
</ins><span class="cx"> }
</span><ins>+
+static EncodedJSValue JSC_HOST_CALL argumentsFuncIterator(ExecState*);
</ins><span class="cx">
</span><span class="cx"> void Arguments::copyToArguments(ExecState* exec, CallFrame* callFrame, uint32_t copyLength, int32_t firstVarArgOffset)
</span><span class="cx"> {
</span><span class="lines">@@ -226,7 +273,7 @@
</span><span class="cx"> if (i < thisObject->m_numArguments) {
</span><span class="cx"> if (!Base::deletePropertyByIndex(cell, exec, i))
</span><span class="cx"> return false;
</span><del>- if (thisObject->tryDeleteArgument(i))
</del><ins>+ if (thisObject->tryDeleteArgument(exec->vm(), i))
</ins><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx"> return JSObject::deletePropertyByIndex(thisObject, exec, i);
</span><span class="lines">@@ -243,7 +290,7 @@
</span><span class="cx"> RELEASE_ASSERT(i < PropertyName::NotAnIndex);
</span><span class="cx"> if (!Base::deleteProperty(cell, exec, propertyName))
</span><span class="cx"> return false;
</span><del>- if (thisObject->tryDeleteArgument(i))
</del><ins>+ if (thisObject->tryDeleteArgument(exec->vm(), i))
</ins><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -288,7 +335,7 @@
</span><span class="cx"> // a. If IsAccessorDescriptor(Desc) is true, then
</span><span class="cx"> if (descriptor.isAccessorDescriptor()) {
</span><span class="cx"> // i. Call the [[Delete]] internal method of map passing P, and false as the arguments.
</span><del>- thisObject->tryDeleteArgument(i);
</del><ins>+ thisObject->tryDeleteArgument(exec->vm(), i);
</ins><span class="cx"> } else { // b. Else
</span><span class="cx"> // i. If Desc.[[Value]] is present, then
</span><span class="cx"> // 1. Call the [[Put]] internal method of map passing P, Desc.[[Value]], and Throw as the arguments.
</span><span class="lines">@@ -297,7 +344,7 @@
</span><span class="cx"> // ii. If Desc.[[Writable]] is present and its value is false, then
</span><span class="cx"> // 1. Call the [[Delete]] internal method of map passing P and false as arguments.
</span><span class="cx"> if (descriptor.writablePresent() && !descriptor.writable())
</span><del>- thisObject->tryDeleteArgument(i);
</del><ins>+ thisObject->tryDeleteArgument(exec->vm(), i);
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx"> return true;
</span><span class="lines">@@ -315,6 +362,15 @@
</span><span class="cx"> return Base::defineOwnProperty(object, exec, propertyName, descriptor, shouldThrow);
</span><span class="cx"> }
</span><span class="cx">
</span><ins>+void Arguments::allocateRegisterArray(VM& vm)
+{
+ ASSERT(!m_registerArray);
+ void* backingStore;
+ if (!vm.heap.tryAllocateStorage(this, registerArraySizeInBytes(), &backingStore))
+ RELEASE_ASSERT_NOT_REACHED();
+ m_registerArray.set(vm, this, static_cast<WriteBarrier<Unknown>*>(backingStore));
+}
+
</ins><span class="cx"> void Arguments::tearOff(CallFrame* callFrame)
</span><span class="cx"> {
</span><span class="cx"> if (isTornOff())
</span><span class="lines">@@ -326,7 +382,7 @@
</span><span class="cx"> // Must be called for the same call frame from which it was created.
</span><span class="cx"> ASSERT(bitwise_cast<WriteBarrier<Unknown>*>(callFrame) == m_registers);
</span><span class="cx">
</span><del>- m_registerArray = std::make_unique<WriteBarrier<Unknown>[]>(m_numArguments);
</del><ins>+ allocateRegisterArray(callFrame->vm());
</ins><span class="cx"> m_registers = m_registerArray.get() - CallFrame::offsetFor(1) - 1;
</span><span class="cx">
</span><span class="cx"> // If we have a captured argument that logically aliases activation storage,
</span><span class="lines">@@ -334,10 +390,10 @@
</span><span class="cx"> // our storage. The simplest way to do this is to revert it to Normal status.
</span><span class="cx"> if (m_slowArgumentData && !m_activation) {
</span><span class="cx"> for (size_t i = 0; i < m_numArguments; ++i) {
</span><del>- if (m_slowArgumentData->slowArguments[i].status != SlowArgument::Captured)
</del><ins>+ if (m_slowArgumentData->slowArguments()[i].status != SlowArgument::Captured)
</ins><span class="cx"> continue;
</span><del>- m_slowArgumentData->slowArguments[i].status = SlowArgument::Normal;
- m_slowArgumentData->slowArguments[i].index = CallFrame::argumentOffset(i);
</del><ins>+ m_slowArgumentData->slowArguments()[i].status = SlowArgument::Normal;
+ m_slowArgumentData->slowArguments()[i].index = CallFrame::argumentOffset(i);
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -366,7 +422,7 @@
</span><span class="cx"> if (!m_numArguments)
</span><span class="cx"> return;
</span><span class="cx">
</span><del>- m_registerArray = std::make_unique<WriteBarrier<Unknown>[]>(m_numArguments);
</del><ins>+ allocateRegisterArray(callFrame->vm());
</ins><span class="cx"> m_registers = m_registerArray.get() - CallFrame::offsetFor(1) - 1;
</span><span class="cx">
</span><span class="cx"> for (size_t i = 0; i < m_numArguments; ++i) {
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeArgumentsh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/Arguments.h (167640 => 167641)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/Arguments.h        2014-04-22 01:34:46 UTC (rev 167640)
+++ trunk/Source/JavaScriptCore/runtime/Arguments.h        2014-04-22 01:37:34 UTC (rev 167641)
</span><span class="lines">@@ -26,7 +26,6 @@
</span><span class="cx">
</span><span class="cx"> #include "CodeOrigin.h"
</span><span class="cx"> #include "JSActivation.h"
</span><del>-#include "JSDestructibleObject.h"
</del><span class="cx"> #include "JSFunction.h"
</span><span class="cx"> #include "JSGlobalObject.h"
</span><span class="cx"> #include "Interpreter.h"
</span><span class="lines">@@ -36,11 +35,11 @@
</span><span class="cx">
</span><span class="cx"> namespace JSC {
</span><span class="cx">
</span><del>-class Arguments : public JSDestructibleObject {
</del><ins>+class Arguments : public JSNonFinalObject {
</ins><span class="cx"> friend class JIT;
</span><span class="cx"> friend class JSArgumentsIterator;
</span><span class="cx"> public:
</span><del>- typedef JSDestructibleObject Base;
</del><ins>+ typedef JSNonFinalObject Base;
</ins><span class="cx">
</span><span class="cx"> static Arguments* create(VM& vm, CallFrame* callFrame)
</span><span class="cx"> {
</span><span class="lines">@@ -68,6 +67,7 @@
</span><span class="cx"> DECLARE_INFO;
</span><span class="cx">
</span><span class="cx"> static void visitChildren(JSCell*, SlotVisitor&);
</span><ins>+ static void copyBackingStore(JSCell*, CopyVisitor&, CopyToken);
</ins><span class="cx">
</span><span class="cx"> void fillArgList(ExecState*, MarkedArgumentBuffer&);
</span><span class="cx">
</span><span class="lines">@@ -111,7 +111,6 @@
</span><span class="cx"> void finishCreation(CallFrame*, InlineCallFrame*);
</span><span class="cx">
</span><span class="cx"> private:
</span><del>- static void destroy(JSCell*);
</del><span class="cx"> static bool getOwnPropertySlot(JSObject*, ExecState*, PropertyName, PropertySlot&);
</span><span class="cx"> static bool getOwnPropertySlotByIndex(JSObject*, ExecState*, unsigned propertyName, PropertySlot&);
</span><span class="cx"> static void getOwnPropertyNames(JSObject*, ExecState*, PropertyNameArray&, EnumerationMode);
</span><span class="lines">@@ -123,13 +122,15 @@
</span><span class="cx"> void createStrictModeCallerIfNecessary(ExecState*);
</span><span class="cx"> void createStrictModeCalleeIfNecessary(ExecState*);
</span><span class="cx">
</span><ins>+ size_t registerArraySizeInBytes() const { return sizeof(WriteBarrier<Unknown>) * m_numArguments; }
+ void allocateRegisterArray(VM&);
</ins><span class="cx"> bool isArgument(size_t);
</span><span class="cx"> bool trySetArgument(VM&, size_t argument, JSValue);
</span><span class="cx"> JSValue tryGetArgument(size_t argument);
</span><span class="cx"> bool isDeletedArgument(size_t);
</span><del>- bool tryDeleteArgument(size_t);
</del><ins>+ bool tryDeleteArgument(VM&, size_t);
</ins><span class="cx"> WriteBarrierBase<Unknown>& argument(size_t);
</span><del>- void allocateSlowArguments();
</del><ins>+ void allocateSlowArguments(VM&);
</ins><span class="cx">
</span><span class="cx"> void init(CallFrame*);
</span><span class="cx">
</span><span class="lines">@@ -146,19 +147,35 @@
</span><span class="cx"> bool m_isStrictMode;
</span><span class="cx">
</span><span class="cx"> WriteBarrierBase<Unknown>* m_registers;
</span><del>- std::unique_ptr<WriteBarrier<Unknown>[]> m_registerArray;
</del><ins>+ CopyWriteBarrier<WriteBarrier<Unknown>> m_registerArray;
</ins><span class="cx">
</span><span class="cx"> public:
</span><span class="cx"> struct SlowArgumentData {
</span><del>- WTF_MAKE_FAST_ALLOCATED;
</del><span class="cx"> public:
</span><ins>+ SlowArgumentData()
+ : m_bytecodeToMachineCaptureOffset(0)
+ {
+ }
</ins><span class="cx">
</span><del>- std::unique_ptr<SlowArgument[]> slowArguments;
- int bytecodeToMachineCaptureOffset; // Add this if you have a bytecode offset into captured registers and you want the machine offset instead. Subtract if you want to do the opposite.
</del><ins>+ SlowArgument* slowArguments()
+ {
+ return reinterpret_cast<SlowArgument*>(WTF::roundUpToMultipleOf<8>(reinterpret_cast<size_t>(this + 1)));
+ }
+
+ int bytecodeToMachineCaptureOffset() const { return m_bytecodeToMachineCaptureOffset; }
+ void setBytecodeToMachineCaptureOffset(int newOffset) { m_bytecodeToMachineCaptureOffset = newOffset; }
+
+ static size_t sizeForNumArguments(unsigned numArguments)
+ {
+ return WTF::roundUpToMultipleOf<8>(sizeof(SlowArgumentData)) + sizeof(SlowArgument) * numArguments;
+ }
+
+ private:
+ int m_bytecodeToMachineCaptureOffset; // Add this if you have a bytecode offset into captured registers and you want the machine offset instead. Subtract if you want to do the opposite.
</ins><span class="cx"> };
</span><span class="cx">
</span><span class="cx"> private:
</span><del>- std::unique_ptr<SlowArgumentData> m_slowArgumentData;
</del><ins>+ CopyWriteBarrier<SlowArgumentData> m_slowArgumentData;
</ins><span class="cx">
</span><span class="cx"> WriteBarrier<JSFunction> m_callee;
</span><span class="cx"> };
</span><span class="lines">@@ -172,34 +189,37 @@
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> inline Arguments::Arguments(CallFrame* callFrame)
</span><del>- : JSDestructibleObject(callFrame->vm(), callFrame->lexicalGlobalObject()->argumentsStructure())
</del><ins>+ : Base(callFrame->vm(), callFrame->lexicalGlobalObject()->argumentsStructure())
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> inline Arguments::Arguments(CallFrame* callFrame, NoParametersType)
</span><del>- : JSDestructibleObject(callFrame->vm(), callFrame->lexicalGlobalObject()->argumentsStructure())
</del><ins>+ : Base(callFrame->vm(), callFrame->lexicalGlobalObject()->argumentsStructure())
</ins><span class="cx"> {
</span><span class="cx"> }
</span><span class="cx">
</span><del>-inline void Arguments::allocateSlowArguments()
</del><ins>+inline void Arguments::allocateSlowArguments(VM& vm)
</ins><span class="cx"> {
</span><del>- if (m_slowArgumentData)
</del><ins>+ if (!!m_slowArgumentData)
</ins><span class="cx"> return;
</span><del>- m_slowArgumentData = std::make_unique<SlowArgumentData>();
- m_slowArgumentData->bytecodeToMachineCaptureOffset = 0;
- m_slowArgumentData->slowArguments = std::make_unique<SlowArgument[]>(m_numArguments);
</del><ins>+
+ void* backingStore;
+ if (!vm.heap.tryAllocateStorage(this, SlowArgumentData::sizeForNumArguments(m_numArguments), &backingStore))
+ RELEASE_ASSERT_NOT_REACHED();
+ m_slowArgumentData.set(vm, this, static_cast<SlowArgumentData*>(backingStore));
+
</ins><span class="cx"> for (size_t i = 0; i < m_numArguments; ++i) {
</span><del>- ASSERT(m_slowArgumentData->slowArguments[i].status == SlowArgument::Normal);
- m_slowArgumentData->slowArguments[i].index = CallFrame::argumentOffset(i);
</del><ins>+ ASSERT(m_slowArgumentData->slowArguments()[i].status == SlowArgument::Normal);
+ m_slowArgumentData->slowArguments()[i].index = CallFrame::argumentOffset(i);
</ins><span class="cx"> }
</span><span class="cx"> }
</span><span class="cx">
</span><del>-inline bool Arguments::tryDeleteArgument(size_t argument)
</del><ins>+inline bool Arguments::tryDeleteArgument(VM& vm, size_t argument)
</ins><span class="cx"> {
</span><span class="cx"> if (!isArgument(argument))
</span><span class="cx"> return false;
</span><del>- allocateSlowArguments();
- m_slowArgumentData->slowArguments[argument].status = SlowArgument::Deleted;
</del><ins>+ allocateSlowArguments(vm);
+ m_slowArgumentData->slowArguments()[argument].status = SlowArgument::Deleted;
</ins><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="cx">
</span><span class="lines">@@ -224,7 +244,7 @@
</span><span class="cx"> return false;
</span><span class="cx"> if (!m_slowArgumentData)
</span><span class="cx"> return false;
</span><del>- if (m_slowArgumentData->slowArguments[argument].status != SlowArgument::Deleted)
</del><ins>+ if (m_slowArgumentData->slowArguments()[argument].status != SlowArgument::Deleted)
</ins><span class="cx"> return false;
</span><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="lines">@@ -233,7 +253,7 @@
</span><span class="cx"> {
</span><span class="cx"> if (argument >= m_numArguments)
</span><span class="cx"> return false;
</span><del>- if (m_slowArgumentData && m_slowArgumentData->slowArguments[argument].status == SlowArgument::Deleted)
</del><ins>+ if (m_slowArgumentData && m_slowArgumentData->slowArguments()[argument].status == SlowArgument::Deleted)
</ins><span class="cx"> return false;
</span><span class="cx"> return true;
</span><span class="cx"> }
</span><span class="lines">@@ -244,11 +264,11 @@
</span><span class="cx"> if (!m_slowArgumentData)
</span><span class="cx"> return m_registers[CallFrame::argumentOffset(argument)];
</span><span class="cx">
</span><del>- int index = m_slowArgumentData->slowArguments[argument].index;
- if (!m_activation || m_slowArgumentData->slowArguments[argument].status != SlowArgument::Captured)
</del><ins>+ int index = m_slowArgumentData->slowArguments()[argument].index;
+ if (!m_activation || m_slowArgumentData->slowArguments()[argument].status != SlowArgument::Captured)
</ins><span class="cx"> return m_registers[index];
</span><span class="cx">
</span><del>- return m_activation->registerAt(index - m_slowArgumentData->bytecodeToMachineCaptureOffset);
</del><ins>+ return m_activation->registerAt(index - m_slowArgumentData->bytecodeToMachineCaptureOffset());
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> inline void Arguments::finishCreation(CallFrame* callFrame)
</span><span class="lines">@@ -269,12 +289,12 @@
</span><span class="cx"> if (codeBlock->hasSlowArguments()) {
</span><span class="cx"> SymbolTable* symbolTable = codeBlock->symbolTable();
</span><span class="cx"> const SlowArgument* slowArguments = codeBlock->machineSlowArguments();
</span><del>- allocateSlowArguments();
</del><ins>+ allocateSlowArguments(callFrame->vm());
</ins><span class="cx"> size_t count = std::min<unsigned>(m_numArguments, symbolTable->parameterCount());
</span><span class="cx"> for (size_t i = 0; i < count; ++i)
</span><del>- m_slowArgumentData->slowArguments[i] = slowArguments[i];
- m_slowArgumentData->bytecodeToMachineCaptureOffset =
- codeBlock->framePointerOffsetToGetActivationRegisters();
</del><ins>+ m_slowArgumentData->slowArguments()[i] = slowArguments[i];
+ m_slowArgumentData->setBytecodeToMachineCaptureOffset(
+ codeBlock->framePointerOffsetToGetActivationRegisters());
</ins><span class="cx"> }
</span><span class="cx">
</span><span class="cx"> // The bytecode generator omits op_tear_off_activation in cases of no
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreruntimeSymbolTableh"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/runtime/SymbolTable.h (167640 => 167641)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/runtime/SymbolTable.h        2014-04-22 01:34:46 UTC (rev 167640)
+++ trunk/Source/JavaScriptCore/runtime/SymbolTable.h        2014-04-22 01:37:34 UTC (rev 167641)
</span><span class="lines">@@ -39,9 +39,7 @@
</span><span class="cx"> namespace JSC {
</span><span class="cx">
</span><span class="cx"> struct SlowArgument {
</span><del>- WTF_MAKE_FAST_ALLOCATED;
</del><span class="cx"> public:
</span><del>-
</del><span class="cx"> enum Status {
</span><span class="cx"> Normal = 0,
</span><span class="cx"> Captured = 1,
</span></span></pre>
</div>
</div>
</body>
</html>