UnlinkedCodeBlock.h 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729
  1. /*
  2. * Copyright (C) 2012, 2013 Apple Inc. All Rights Reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. * 1. Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
  14. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  15. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  16. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
  17. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  18. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  19. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  20. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  21. * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  23. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #ifndef UnlinkedCodeBlock_h
  26. #define UnlinkedCodeBlock_h
  27. #include "BytecodeConventions.h"
  28. #include "CodeCache.h"
  29. #include "CodeSpecializationKind.h"
  30. #include "CodeType.h"
  31. #include "ExpressionRangeInfo.h"
  32. #include "Identifier.h"
  33. #include "JSCBridgeToll.h"
  34. #include "JSCell.h"
  35. #include "JSString.h"
  36. #include "LineInfo.h"
  37. #include "ParserModes.h"
  38. #include "RegExp.h"
  39. #include "SpecialPointer.h"
  40. #include "SymbolTable.h"
  41. #include <wtf/RefCountedArray.h>
  42. #include <wtf/Vector.h>
  43. namespace JSC {
  44. class Debugger;
  45. class FunctionBodyNode;
  46. class FunctionExecutable;
  47. class FunctionParameters;
  48. class JSScope;
  49. struct ParserError;
  50. class ScriptExecutable;
  51. class SourceCode;
  52. class SourceProvider;
  53. class SharedSymbolTable;
  54. class UnlinkedCodeBlock;
  55. class UnlinkedFunctionCodeBlock;
  56. typedef unsigned UnlinkedValueProfile;
  57. typedef unsigned UnlinkedArrayProfile;
  58. typedef unsigned UnlinkedArrayAllocationProfile;
  59. typedef unsigned UnlinkedObjectAllocationProfile;
  60. typedef unsigned UnlinkedLLIntCallLinkInfo;
  61. struct ExecutableInfo {
  62. ExecutableInfo(bool needsActivation, bool usesEval, bool isStrictMode, bool isConstructor)
  63. : m_needsActivation(needsActivation)
  64. , m_usesEval(usesEval)
  65. , m_isStrictMode(isStrictMode)
  66. , m_isConstructor(isConstructor)
  67. {
  68. }
  69. bool m_needsActivation;
  70. bool m_usesEval;
  71. bool m_isStrictMode;
  72. bool m_isConstructor;
  73. };
  74. class UnlinkedFunctionExecutable : public JSCell {
  75. public:
  76. friend class CodeCache;
  77. typedef JSCell Base;
  78. static UnlinkedFunctionExecutable* create(VM* vm, const SourceCode& source, FunctionBodyNode* node)
  79. {
  80. UnlinkedFunctionExecutable* instance = new (NotNull, allocateCell<UnlinkedFunctionExecutable>(vm->heap)) UnlinkedFunctionExecutable(vm, vm->unlinkedFunctionExecutableStructure.get(), source, node);
  81. instance->finishCreation(*vm);
  82. return instance;
  83. }
  84. const Identifier& name() const { return m_name; }
  85. const Identifier& inferredName() const { return m_inferredName; }
  86. JSString* nameValue() const { return m_nameValue.get(); }
  87. SharedSymbolTable* symbolTable(CodeSpecializationKind kind)
  88. {
  89. return (kind == CodeForCall) ? m_symbolTableForCall.get() : m_symbolTableForConstruct.get();
  90. }
  91. size_t parameterCount() const;
  92. bool isInStrictContext() const { return m_isInStrictContext; }
  93. FunctionNameIsInScopeToggle functionNameIsInScopeToggle() const { return m_functionNameIsInScopeToggle; }
  94. unsigned firstLineOffset() const { return m_firstLineOffset; }
  95. unsigned lineCount() const { return m_lineCount; }
  96. unsigned functionStartOffset() const { return m_functionStartOffset; }
  97. unsigned functionStartColumn() const { return m_functionStartColumn; }
  98. unsigned startOffset() const { return m_startOffset; }
  99. unsigned sourceLength() { return m_sourceLength; }
  100. String paramString() const;
  101. UnlinkedFunctionCodeBlock* codeBlockFor(VM&, JSScope*, const SourceCode&, CodeSpecializationKind, DebuggerMode, ProfilerMode, ParserError&);
  102. static UnlinkedFunctionExecutable* fromGlobalCode(const Identifier&, ExecState*, Debugger*, const SourceCode&, JSObject** exception);
  103. FunctionExecutable* link(VM&, const SourceCode&, size_t lineOffset, size_t sourceOffset);
  104. void clearCodeForRecompilation()
  105. {
  106. m_symbolTableForCall.clear();
  107. m_symbolTableForConstruct.clear();
  108. m_codeBlockForCall.clear();
  109. m_codeBlockForConstruct.clear();
  110. }
  111. FunctionParameters* parameters() { return m_parameters.get(); }
  112. void recordParse(CodeFeatures features, bool hasCapturedVariables, int firstLine, int lastLine)
  113. {
  114. m_features = features;
  115. m_hasCapturedVariables = hasCapturedVariables;
  116. m_lineCount = lastLine - firstLine;
  117. }
  118. bool forceUsesArguments() const { return m_forceUsesArguments; }
  119. CodeFeatures features() const { return m_features; }
  120. bool hasCapturedVariables() const { return m_hasCapturedVariables; }
  121. static const bool needsDestruction = true;
  122. static const bool hasImmortalStructure = true;
  123. static void destroy(JSCell*);
  124. private:
  125. UnlinkedFunctionExecutable(VM*, Structure*, const SourceCode&, FunctionBodyNode*);
  126. WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForCall;
  127. WriteBarrier<UnlinkedFunctionCodeBlock> m_codeBlockForConstruct;
  128. unsigned m_numCapturedVariables : 29;
  129. bool m_forceUsesArguments : 1;
  130. bool m_isInStrictContext : 1;
  131. bool m_hasCapturedVariables : 1;
  132. Identifier m_name;
  133. Identifier m_inferredName;
  134. WriteBarrier<JSString> m_nameValue;
  135. WriteBarrier<SharedSymbolTable> m_symbolTableForCall;
  136. WriteBarrier<SharedSymbolTable> m_symbolTableForConstruct;
  137. RefPtr<FunctionParameters> m_parameters;
  138. unsigned m_firstLineOffset;
  139. unsigned m_lineCount;
  140. unsigned m_functionStartOffset;
  141. unsigned m_functionStartColumn;
  142. unsigned m_startOffset;
  143. unsigned m_sourceLength;
  144. CodeFeatures m_features;
  145. FunctionNameIsInScopeToggle m_functionNameIsInScopeToggle;
  146. protected:
  147. void finishCreation(VM& vm)
  148. {
  149. Base::finishCreation(vm);
  150. m_nameValue.set(vm, this, jsString(&vm, name().string()));
  151. }
  152. static void visitChildren(JSCell*, SlotVisitor&);
  153. public:
  154. static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
  155. {
  156. return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedFunctionExecutableType, StructureFlags), &s_info);
  157. }
  158. static const unsigned StructureFlags = OverridesVisitChildren | JSCell::StructureFlags;
  159. static const ClassInfo s_info;
  160. };
  161. struct UnlinkedStringJumpTable {
  162. typedef HashMap<RefPtr<StringImpl>, int32_t> StringOffsetTable;
  163. StringOffsetTable offsetTable;
  164. inline int32_t offsetForValue(StringImpl* value, int32_t defaultOffset)
  165. {
  166. StringOffsetTable::const_iterator end = offsetTable.end();
  167. StringOffsetTable::const_iterator loc = offsetTable.find(value);
  168. if (loc == end)
  169. return defaultOffset;
  170. return loc->value;
  171. }
  172. };
  173. struct UnlinkedSimpleJumpTable {
  174. Vector<int32_t> branchOffsets;
  175. int32_t min;
  176. int32_t offsetForValue(int32_t value, int32_t defaultOffset);
  177. void add(int32_t key, int32_t offset)
  178. {
  179. if (!branchOffsets[key])
  180. branchOffsets[key] = offset;
  181. }
  182. };
  183. struct UnlinkedHandlerInfo {
  184. uint32_t start;
  185. uint32_t end;
  186. uint32_t target;
  187. uint32_t scopeDepth;
  188. };
  189. struct UnlinkedInstruction {
  190. UnlinkedInstruction() { u.operand = 0; }
  191. UnlinkedInstruction(OpcodeID opcode) { u.opcode = opcode; }
  192. UnlinkedInstruction(int operand) { u.operand = operand; }
  193. union {
  194. OpcodeID opcode;
  195. int32_t operand;
  196. } u;
  197. };
  198. class UnlinkedCodeBlock : public JSCell {
  199. #if ENABLE(DETACHED_JIT)
  200. friend void JSCBridgeToll::prepare(CodeBlock *);
  201. #endif
  202. public:
  203. typedef JSCell Base;
  204. static const bool needsDestruction = true;
  205. static const bool hasImmortalStructure = true;
  206. enum { CallFunction, ApplyFunction };
  207. bool isConstructor() const { return m_isConstructor; }
  208. bool isStrictMode() const { return m_isStrictMode; }
  209. bool usesEval() const { return m_usesEval; }
  210. bool needsFullScopeChain() const { return m_needsFullScopeChain; }
  211. void setNeedsFullScopeChain(bool needsFullScopeChain) { m_needsFullScopeChain = needsFullScopeChain; }
  212. void addExpressionInfo(unsigned instructionOffset, int divot,
  213. int startOffset, int endOffset, unsigned line, unsigned column);
  214. bool hasExpressionInfo() { return m_expressionInfo.size(); }
  215. // Special registers
  216. void setThisRegister(int thisRegister) { m_thisRegister = thisRegister; }
  217. void setActivationRegister(int activationRegister) { m_activationRegister = activationRegister; }
  218. void setArgumentsRegister(int argumentsRegister) { m_argumentsRegister = argumentsRegister; }
  219. bool usesArguments() const { return m_argumentsRegister != -1; }
  220. int argumentsRegister() const { return m_argumentsRegister; }
  221. bool usesGlobalObject() const { return m_globalObjectRegister != -1; }
  222. void setGlobalObjectRegister(int globalObjectRegister) { m_globalObjectRegister = globalObjectRegister; }
  223. int globalObjectRegister() const { return m_globalObjectRegister; }
  224. // Parameter information
  225. void setNumParameters(int newValue) { m_numParameters = newValue; }
  226. void addParameter() { m_numParameters++; }
  227. unsigned numParameters() const { return m_numParameters; }
  228. unsigned addRegExp(RegExp* r)
  229. {
  230. createRareDataIfNecessary();
  231. unsigned size = m_rareData->m_regexps.size();
  232. m_rareData->m_regexps.append(WriteBarrier<RegExp>(*m_vm, this, r));
  233. return size;
  234. }
  235. unsigned numberOfRegExps() const
  236. {
  237. if (!m_rareData)
  238. return 0;
  239. return m_rareData->m_regexps.size();
  240. }
  241. RegExp* regexp(int index) const { ASSERT(m_rareData); return m_rareData->m_regexps[index].get(); }
  242. // Constant Pools
  243. size_t numberOfIdentifiers() const { return m_identifiers.size(); }
  244. void addIdentifier(const Identifier& i) { return m_identifiers.append(i); }
  245. const Identifier& identifier(int index) const { return m_identifiers[index]; }
  246. const Vector<Identifier>& identifiers() const { return m_identifiers; }
  247. size_t numberOfConstantRegisters() const { return m_constantRegisters.size(); }
  248. unsigned addConstant(JSValue v)
  249. {
  250. unsigned result = m_constantRegisters.size();
  251. m_constantRegisters.append(WriteBarrier<Unknown>());
  252. m_constantRegisters.last().set(*m_vm, this, v);
  253. return result;
  254. }
  255. unsigned addOrFindConstant(JSValue);
  256. const Vector<WriteBarrier<Unknown> >& constantRegisters() { return m_constantRegisters; }
  257. const WriteBarrier<Unknown>& constantRegister(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex]; }
  258. ALWAYS_INLINE bool isConstantRegisterIndex(int index) const { return index >= FirstConstantRegisterIndex; }
  259. ALWAYS_INLINE JSValue getConstant(int index) const { return m_constantRegisters[index - FirstConstantRegisterIndex].get(); }
  260. // Jumps
  261. size_t numberOfJumpTargets() const { return m_jumpTargets.size(); }
  262. void addJumpTarget(unsigned jumpTarget) { m_jumpTargets.append(jumpTarget); }
  263. unsigned jumpTarget(int index) const { return m_jumpTargets[index]; }
  264. unsigned lastJumpTarget() const { return m_jumpTargets.last(); }
  265. void setIsNumericCompareFunction(bool isNumericCompareFunction) { m_isNumericCompareFunction = isNumericCompareFunction; }
  266. bool isNumericCompareFunction() const { return m_isNumericCompareFunction; }
  267. void shrinkToFit()
  268. {
  269. m_jumpTargets.shrinkToFit();
  270. m_identifiers.shrinkToFit();
  271. m_constantRegisters.shrinkToFit();
  272. m_functionDecls.shrinkToFit();
  273. m_functionExprs.shrinkToFit();
  274. m_propertyAccessInstructions.shrinkToFit();
  275. m_expressionInfo.shrinkToFit();
  276. #if ENABLE(BYTECODE_COMMENTS)
  277. m_bytecodeComments.shrinkToFit();
  278. #endif
  279. if (m_rareData) {
  280. m_rareData->m_exceptionHandlers.shrinkToFit();
  281. m_rareData->m_regexps.shrinkToFit();
  282. m_rareData->m_constantBuffers.shrinkToFit();
  283. m_rareData->m_immediateSwitchJumpTables.shrinkToFit();
  284. m_rareData->m_characterSwitchJumpTables.shrinkToFit();
  285. m_rareData->m_stringSwitchJumpTables.shrinkToFit();
  286. m_rareData->m_expressionInfoFatPositions.shrinkToFit();
  287. }
  288. }
  289. unsigned numberOfInstructions() const { return m_unlinkedInstructions.size(); }
  290. RefCountedArray_shared<UnlinkedInstruction>& instructions() { return m_unlinkedInstructions; }
  291. const RefCountedArray_shared<UnlinkedInstruction>& instructions() const { return m_unlinkedInstructions; }
  292. int m_numVars;
  293. int m_numCapturedVars;
  294. int m_numCalleeRegisters;
  295. // Jump Tables
  296. size_t numberOfImmediateSwitchJumpTables() const { return m_rareData ? m_rareData->m_immediateSwitchJumpTables.size() : 0; }
  297. UnlinkedSimpleJumpTable& addImmediateSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_immediateSwitchJumpTables.append(UnlinkedSimpleJumpTable()); return m_rareData->m_immediateSwitchJumpTables.last(); }
  298. UnlinkedSimpleJumpTable& immediateSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_immediateSwitchJumpTables[tableIndex]; }
  299. size_t numberOfCharacterSwitchJumpTables() const { return m_rareData ? m_rareData->m_characterSwitchJumpTables.size() : 0; }
  300. UnlinkedSimpleJumpTable& addCharacterSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_characterSwitchJumpTables.append(UnlinkedSimpleJumpTable()); return m_rareData->m_characterSwitchJumpTables.last(); }
  301. UnlinkedSimpleJumpTable& characterSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_characterSwitchJumpTables[tableIndex]; }
  302. size_t numberOfStringSwitchJumpTables() const { return m_rareData ? m_rareData->m_stringSwitchJumpTables.size() : 0; }
  303. UnlinkedStringJumpTable& addStringSwitchJumpTable() { createRareDataIfNecessary(); m_rareData->m_stringSwitchJumpTables.append(UnlinkedStringJumpTable()); return m_rareData->m_stringSwitchJumpTables.last(); }
  304. UnlinkedStringJumpTable& stringSwitchJumpTable(int tableIndex) { ASSERT(m_rareData); return m_rareData->m_stringSwitchJumpTables[tableIndex]; }
  305. unsigned addFunctionDecl(UnlinkedFunctionExecutable* n)
  306. {
  307. unsigned size = m_functionDecls.size();
  308. m_functionDecls.append(WriteBarrier<UnlinkedFunctionExecutable>());
  309. m_functionDecls.last().set(*m_vm, this, n);
  310. return size;
  311. }
  312. UnlinkedFunctionExecutable* functionDecl(int index) { return m_functionDecls[index].get(); }
  313. size_t numberOfFunctionDecls() { return m_functionDecls.size(); }
  314. unsigned addFunctionExpr(UnlinkedFunctionExecutable* n)
  315. {
  316. unsigned size = m_functionExprs.size();
  317. m_functionExprs.append(WriteBarrier<UnlinkedFunctionExecutable>());
  318. m_functionExprs.last().set(*m_vm, this, n);
  319. return size;
  320. }
  321. UnlinkedFunctionExecutable* functionExpr(int index) { return m_functionExprs[index].get(); }
  322. size_t numberOfFunctionExprs() { return m_functionExprs.size(); }
  323. // Exception handling support
  324. size_t numberOfExceptionHandlers() const { return m_rareData ? m_rareData->m_exceptionHandlers.size() : 0; }
  325. void addExceptionHandler(const UnlinkedHandlerInfo& hanler) { createRareDataIfNecessary(); return m_rareData->m_exceptionHandlers.append(hanler); }
  326. UnlinkedHandlerInfo& exceptionHandler(int index) { ASSERT(m_rareData); return m_rareData->m_exceptionHandlers[index]; }
  327. SharedSymbolTable* symbolTable() const { return m_symbolTable.get(); }
  328. VM* vm() const { return m_vm; }
  329. unsigned addResolve() { return m_resolveOperationCount++; }
  330. unsigned numberOfResolveOperations() const { return m_resolveOperationCount; }
  331. unsigned addPutToBase() { return m_putToBaseOperationCount++; }
  332. unsigned numberOfPutToBaseOperations() const { return m_putToBaseOperationCount; }
  333. UnlinkedArrayProfile addArrayProfile() { return m_arrayProfileCount++; }
  334. unsigned numberOfArrayProfiles() { return m_arrayProfileCount; }
  335. UnlinkedArrayAllocationProfile addArrayAllocationProfile() { return m_arrayAllocationProfileCount++; }
  336. unsigned numberOfArrayAllocationProfiles() { return m_arrayAllocationProfileCount; }
  337. UnlinkedObjectAllocationProfile addObjectAllocationProfile() { return m_objectAllocationProfileCount++; }
  338. unsigned numberOfObjectAllocationProfiles() { return m_objectAllocationProfileCount; }
  339. UnlinkedValueProfile addValueProfile() { return m_valueProfileCount++; }
  340. unsigned numberOfValueProfiles() { return m_valueProfileCount; }
  341. UnlinkedLLIntCallLinkInfo addLLIntCallLinkInfo() { return m_llintCallLinkInfoCount++; }
  342. unsigned numberOfLLintCallLinkInfos() { return m_llintCallLinkInfoCount; }
  343. CodeType codeType() const { return m_codeType; }
  344. int thisRegister() const { return m_thisRegister; }
  345. int activationRegister() const { return m_activationRegister; }
  346. void addPropertyAccessInstruction(unsigned propertyAccessInstruction)
  347. {
  348. m_propertyAccessInstructions.append(propertyAccessInstruction);
  349. }
  350. size_t numberOfPropertyAccessInstructions() const { return m_propertyAccessInstructions.size(); }
  351. const Vector<unsigned>& propertyAccessInstructions() const { return m_propertyAccessInstructions; }
  352. typedef Vector<JSValue> ConstantBuffer;
  353. size_t constantBufferCount() { ASSERT(m_rareData); return m_rareData->m_constantBuffers.size(); }
  354. unsigned addConstantBuffer(unsigned length)
  355. {
  356. createRareDataIfNecessary();
  357. unsigned size = m_rareData->m_constantBuffers.size();
  358. m_rareData->m_constantBuffers.append(Vector<JSValue>(length));
  359. return size;
  360. }
  361. const ConstantBuffer& constantBuffer(unsigned index) const
  362. {
  363. ASSERT(m_rareData);
  364. return m_rareData->m_constantBuffers[index];
  365. }
  366. ConstantBuffer& constantBuffer(unsigned index)
  367. {
  368. ASSERT(m_rareData);
  369. return m_rareData->m_constantBuffers[index];
  370. }
  371. bool hasRareData() const { return m_rareData; }
  372. int lineNumberForBytecodeOffset(unsigned bytecodeOffset);
  373. void expressionRangeForBytecodeOffset(unsigned bytecodeOffset, int& divot,
  374. int& startOffset, int& endOffset, unsigned& line, unsigned& column);
  375. void recordParse(CodeFeatures features, bool hasCapturedVariables, unsigned firstLine, unsigned lineCount)
  376. {
  377. m_features = features;
  378. m_hasCapturedVariables = hasCapturedVariables;
  379. m_firstLine = firstLine;
  380. m_lineCount = lineCount;
  381. }
  382. CodeFeatures codeFeatures() const { return m_features; }
  383. bool hasCapturedVariables() const { return m_hasCapturedVariables; }
  384. unsigned firstLine() const { return m_firstLine; }
  385. unsigned lineCount() const { return m_lineCount; }
  386. PassRefPtr<CodeCache> codeCacheForEval()
  387. {
  388. if (m_codeType == GlobalCode)
  389. return m_vm->codeCache();
  390. createRareDataIfNecessary();
  391. if (!m_rareData->m_evalCodeCache)
  392. m_rareData->m_evalCodeCache = CodeCache::create(CodeCache::NonGlobalCodeCache);
  393. return m_rareData->m_evalCodeCache.get();
  394. }
  395. protected:
  396. UnlinkedCodeBlock(VM*, Structure*, CodeType, const ExecutableInfo&);
  397. ~UnlinkedCodeBlock();
  398. void finishCreation(VM& vm)
  399. {
  400. Base::finishCreation(vm);
  401. if (codeType() == GlobalCode)
  402. return;
  403. m_symbolTable.set(vm, this, SharedSymbolTable::create(vm));
  404. }
  405. private:
  406. void createRareDataIfNecessary()
  407. {
  408. if (!m_rareData)
  409. m_rareData = adoptPtr(new RareData);
  410. }
  411. RefCountedArray_shared<UnlinkedInstruction> m_unlinkedInstructions;
  412. int m_numParameters;
  413. VM* m_vm;
  414. int m_thisRegister;
  415. int m_argumentsRegister;
  416. int m_activationRegister;
  417. int m_globalObjectRegister;
  418. bool m_needsFullScopeChain : 1;
  419. bool m_usesEval : 1;
  420. bool m_isNumericCompareFunction : 1;
  421. bool m_isStrictMode : 1;
  422. bool m_isConstructor : 1;
  423. bool m_hasCapturedVariables : 1;
  424. unsigned m_firstLine;
  425. unsigned m_lineCount;
  426. CodeFeatures m_features;
  427. CodeType m_codeType;
  428. Vector_shared<unsigned> m_jumpTargets;
  429. // Constant Pools
  430. Vector<Identifier> m_identifiers;
  431. Vector<WriteBarrier<Unknown> > m_constantRegisters;
  432. typedef Vector<WriteBarrier<UnlinkedFunctionExecutable> > FunctionExpressionVector;
  433. FunctionExpressionVector m_functionDecls;
  434. FunctionExpressionVector m_functionExprs;
  435. WriteBarrier<SharedSymbolTable> m_symbolTable;
  436. Vector<unsigned> m_propertyAccessInstructions;
  437. #if ENABLE(BYTECODE_COMMENTS)
  438. Vector<Comment> m_bytecodeComments;
  439. size_t m_bytecodeCommentIterator;
  440. #endif
  441. unsigned m_resolveOperationCount;
  442. unsigned m_putToBaseOperationCount;
  443. unsigned m_arrayProfileCount;
  444. unsigned m_arrayAllocationProfileCount;
  445. unsigned m_objectAllocationProfileCount;
  446. unsigned m_valueProfileCount;
  447. unsigned m_llintCallLinkInfoCount;
  448. public:
  449. struct RareData {
  450. #if ENABLE(JIT) && ENABLE(DETACHED_JIT)
  451. DETACHED_JIT_MAKE_SHARED_DATA_ALLOCATED;
  452. #else
  453. WTF_MAKE_FAST_ALLOCATED;
  454. #endif
  455. public:
  456. Vector<UnlinkedHandlerInfo> m_exceptionHandlers;
  457. // Rare Constants
  458. Vector_shared<WriteBarrier<RegExp> > m_regexps;
  459. // Buffers used for large array literals
  460. Vector<ConstantBuffer> m_constantBuffers;
  461. // Jump Tables
  462. Vector_shared<UnlinkedSimpleJumpTable> m_immediateSwitchJumpTables;
  463. Vector_shared<UnlinkedSimpleJumpTable> m_characterSwitchJumpTables;
  464. Vector_shared<UnlinkedStringJumpTable> m_stringSwitchJumpTables;
  465. RefPtr<CodeCache> m_evalCodeCache;
  466. Vector<ExpressionRangeInfo::FatPosition> m_expressionInfoFatPositions;
  467. };
  468. private:
  469. OwnPtr<RareData> m_rareData;
  470. Vector<ExpressionRangeInfo> m_expressionInfo;
  471. protected:
  472. static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
  473. static void visitChildren(JSCell*, SlotVisitor&);
  474. public:
  475. static const ClassInfo s_info;
  476. };
  477. class UnlinkedGlobalCodeBlock : public UnlinkedCodeBlock {
  478. public:
  479. typedef UnlinkedCodeBlock Base;
  480. protected:
  481. UnlinkedGlobalCodeBlock(VM* vm, Structure* structure, CodeType codeType, const ExecutableInfo& info)
  482. : Base(vm, structure, codeType, info)
  483. {
  484. }
  485. static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
  486. static const ClassInfo s_info;
  487. };
  488. class UnlinkedProgramCodeBlock : public UnlinkedGlobalCodeBlock {
  489. private:
  490. friend class CodeCache;
  491. static UnlinkedProgramCodeBlock* create(VM* vm, const ExecutableInfo& info)
  492. {
  493. UnlinkedProgramCodeBlock* instance = new (NotNull, allocateCell<UnlinkedProgramCodeBlock>(vm->heap)) UnlinkedProgramCodeBlock(vm, vm->unlinkedProgramCodeBlockStructure.get(), info);
  494. instance->finishCreation(*vm);
  495. return instance;
  496. }
  497. public:
  498. typedef UnlinkedGlobalCodeBlock Base;
  499. static void destroy(JSCell*);
  500. void addFunctionDeclaration(VM& vm, const Identifier& name, UnlinkedFunctionExecutable* functionExecutable)
  501. {
  502. m_functionDeclarations.append(std::make_pair(name, WriteBarrier<UnlinkedFunctionExecutable>(vm, this, functionExecutable)));
  503. }
  504. void addVariableDeclaration(const Identifier& name, bool isConstant)
  505. {
  506. m_varDeclarations.append(std::make_pair(name, isConstant));
  507. }
  508. typedef Vector<std::pair<Identifier, bool> > VariableDeclations;
  509. typedef Vector<std::pair<Identifier, WriteBarrier<UnlinkedFunctionExecutable> > > FunctionDeclations;
  510. const VariableDeclations& variableDeclarations() const { return m_varDeclarations; }
  511. const FunctionDeclations& functionDeclarations() const { return m_functionDeclarations; }
  512. static void visitChildren(JSCell*, SlotVisitor&);
  513. private:
  514. UnlinkedProgramCodeBlock(VM* vm, Structure* structure, const ExecutableInfo& info)
  515. : Base(vm, structure, GlobalCode, info)
  516. {
  517. }
  518. VariableDeclations m_varDeclarations;
  519. FunctionDeclations m_functionDeclarations;
  520. public:
  521. static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
  522. {
  523. return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedProgramCodeBlockType, StructureFlags), &s_info);
  524. }
  525. static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
  526. static const ClassInfo s_info;
  527. };
  528. class UnlinkedEvalCodeBlock : public UnlinkedGlobalCodeBlock {
  529. private:
  530. friend class CodeCache;
  531. static UnlinkedEvalCodeBlock* create(VM* vm, const ExecutableInfo& info)
  532. {
  533. UnlinkedEvalCodeBlock* instance = new (NotNull, allocateCell<UnlinkedEvalCodeBlock>(vm->heap)) UnlinkedEvalCodeBlock(vm, vm->unlinkedEvalCodeBlockStructure.get(), info);
  534. instance->finishCreation(*vm);
  535. return instance;
  536. }
  537. public:
  538. typedef UnlinkedGlobalCodeBlock Base;
  539. static void destroy(JSCell*);
  540. const Identifier& variable(unsigned index) { return m_variables[index]; }
  541. unsigned numVariables() { return m_variables.size(); }
  542. void adoptVariables(Vector<Identifier, 0, UnsafeVectorOverflow>& variables)
  543. {
  544. ASSERT(m_variables.isEmpty());
  545. m_variables.swap(variables);
  546. }
  547. private:
  548. UnlinkedEvalCodeBlock(VM* vm, Structure* structure, const ExecutableInfo& info)
  549. : Base(vm, structure, EvalCode, info)
  550. {
  551. }
  552. Vector<Identifier, 0, UnsafeVectorOverflow> m_variables;
  553. public:
  554. static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
  555. {
  556. return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedEvalCodeBlockType, StructureFlags), &s_info);
  557. }
  558. static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
  559. static const ClassInfo s_info;
  560. };
  561. class UnlinkedFunctionCodeBlock : public UnlinkedCodeBlock {
  562. public:
  563. static UnlinkedFunctionCodeBlock* create(VM* vm, CodeType codeType, const ExecutableInfo& info)
  564. {
  565. UnlinkedFunctionCodeBlock* instance = new (NotNull, allocateCell<UnlinkedFunctionCodeBlock>(vm->heap)) UnlinkedFunctionCodeBlock(vm, vm->unlinkedFunctionCodeBlockStructure.get(), codeType, info);
  566. instance->finishCreation(*vm);
  567. return instance;
  568. }
  569. typedef UnlinkedCodeBlock Base;
  570. static void destroy(JSCell*);
  571. private:
  572. UnlinkedFunctionCodeBlock(VM* vm, Structure* structure, CodeType codeType, const ExecutableInfo& info)
  573. : Base(vm, structure, codeType, info)
  574. {
  575. }
  576. public:
  577. static Structure* createStructure(VM& vm, JSGlobalObject* globalObject, JSValue proto)
  578. {
  579. return Structure::create(vm, globalObject, proto, TypeInfo(UnlinkedFunctionCodeBlockType, StructureFlags), &s_info);
  580. }
  581. static const unsigned StructureFlags = OverridesVisitChildren | Base::StructureFlags;
  582. static const ClassInfo s_info;
  583. };
  584. }
  585. #endif // UnlinkedCodeBlock_h