Changeset 214905 in webkit for trunk/Source/JavaScriptCore/interpreter
- Timestamp:
- Apr 4, 2017, 3:23:37 PM (8 years ago)
- Location:
- trunk/Source/JavaScriptCore/interpreter
- Files:
-
- 1 added
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/Source/JavaScriptCore/interpreter/CallFrame.cpp
r212483 r214905 32 32 #include "JSCInlines.h" 33 33 #include "VMEntryScope.h" 34 #include "WasmContext.h" 34 35 #include <wtf/StringPrintStream.h> 35 36 … … 186 187 JSGlobalObject* CallFrame::vmEntryGlobalObject() 187 188 { 188 if (callee()->isObject()) { 189 RELEASE_ASSERT(callee().isCell()); 190 if (callee().asCell()->isObject()) { 189 191 if (this == lexicalGlobalObject()->globalExec()) 190 192 return lexicalGlobalObject(); … … 198 200 } 199 201 202 JSGlobalObject* CallFrame::vmEntryGlobalObject(VM& vm) 203 { 204 if (callee().isCell() && callee().asCell()->isObject()) { 205 if (this == lexicalGlobalObject()->globalExec()) 206 return lexicalGlobalObject(); 207 } 208 209 // For any ExecState that's not a globalExec, the 210 // dynamic global object must be set since code is running 211 ASSERT(vm.entryScope); 212 return vm.entryScope->globalObject(); 213 } 214 215 JSGlobalObject* CallFrame::wasmAwareLexicalGlobalObject(VM& vm) 216 { 217 #if ENABLE(WEBASSEMBLY) 218 if (!callee().isWasm()) 219 return lexicalGlobalObject(); 220 return Wasm::loadContext(vm)->globalObject(); 221 #else 222 UNUSED_PARAM(vm); 223 return lexicalGlobalObject(); 224 #endif 225 } 226 227 bool CallFrame::isAnyWasmCallee() 228 { 229 CalleeBits callee = this->callee(); 230 if (callee.isWasm()) 231 return true; 232 233 ASSERT(callee.isCell()); 234 if (!!callee.rawPtr() && isWebAssemblyToJSCallee(callee.asCell())) 235 return true; 236 237 return false; 238 } 239 200 240 CallFrame* CallFrame::callerFrame(VMEntryFrame*& currVMEntryFrame) 201 241 { … … 220 260 SourceOrigin CallFrame::callerSourceOrigin() 221 261 { 262 RELEASE_ASSERT(callee().isCell()); 263 VM* vm = &this->vm(); 222 264 SourceOrigin sourceOrigin; 223 265 bool haveSkippedFirstFrame = false; 224 StackVisitor::visit(this, [&](StackVisitor& visitor) {266 StackVisitor::visit(this, vm, [&](StackVisitor& visitor) { 225 267 if (!std::exchange(haveSkippedFirstFrame, true)) 226 268 return StackVisitor::Status::Continue; -
trunk/Source/JavaScriptCore/interpreter/CallFrame.h
r212692 r214905 24 24 25 25 #include "AbstractPC.h" 26 #include "CalleeBits.h" 26 27 #include "MacroAssemblerCodeRef.h" 27 28 #include "Register.h" … … 87 88 static const int headerSizeInRegisters = CallFrameSlot::argumentCount + 1; 88 89 89 JSValue calleeAsValue() const { return this[CallFrameSlot::callee].jsValue(); } 90 JSObject* jsCallee() const { return this[CallFrameSlot::callee].object(); } 91 JSCell* callee() const { return this[CallFrameSlot::callee].unboxedCell(); } 92 SUPPRESS_ASAN JSValue unsafeCallee() const { return this[CallFrameSlot::callee].asanUnsafeJSValue(); } 90 JSValue calleeAsValue() const 91 { 92 ASSERT(!callee().isWasm()); 93 return this[CallFrameSlot::callee].jsValue(); 94 } 95 JSObject* jsCallee() const 96 { 97 ASSERT(!callee().isWasm()); 98 return this[CallFrameSlot::callee].object(); 99 } 100 CalleeBits callee() const { return CalleeBits(this[CallFrameSlot::callee].pointer()); } 101 SUPPRESS_ASAN CalleeBits unsafeCallee() const { return CalleeBits(this[CallFrameSlot::callee].pointer()); } 93 102 CodeBlock* codeBlock() const { return this[CallFrameSlot::codeBlock].Register::codeBlock(); } 94 103 CodeBlock** addressOfCodeBlock() const { return bitwise_cast<CodeBlock**>(this + CallFrameSlot::codeBlock); } … … 99 108 return this[scopeRegisterOffset].Register::scope(); 100 109 } 101 102 110 // Global object in which execution began. 111 // This variant is not safe to call from a Wasm frame. 103 112 JS_EXPORT_PRIVATE JSGlobalObject* vmEntryGlobalObject(); 113 // This variant is safe to call from a Wasm frame. 114 JSGlobalObject* vmEntryGlobalObject(VM&); 115 116 JSGlobalObject* wasmAwareLexicalGlobalObject(VM&); 117 118 bool isAnyWasmCallee(); 104 119 105 120 // Global object in which the currently executing code was defined. … … 258 273 // FIXME: This method is improper. We rely on the fact that we can call it with a null 259 274 // receiver. We should always be using StackVisitor directly. 275 // It's only valid to call this from a non-wasm top frame. 260 276 template <typename Functor> void iterate(const Functor& functor) 261 277 { 262 StackVisitor::visit<Functor>(this, functor); 278 VM* vm; 279 void* rawThis = this; 280 if (!!rawThis) { 281 RELEASE_ASSERT(callee().isCell()); 282 vm = &this->vm(); 283 } else 284 vm = nullptr; 285 StackVisitor::visit<Functor>(this, vm, functor); 263 286 } 264 287 -
trunk/Source/JavaScriptCore/interpreter/Interpreter.cpp
r214645 r214905 473 473 474 474 if (m_remainingCapacityForFrameCapture) { 475 if ( !visitor->isWasmFrame()476 && !!visitor->codeBlock()477 475 if (visitor->isWasmFrame()) 476 m_results.append(StackFrame::wasm()); 477 else if (!!visitor->codeBlock() && !visitor->codeBlock()->unlinkedCodeBlock()->isBuiltinFunction()) { 478 478 m_results.append( 479 StackFrame(m_vm, visitor->callee() , visitor->codeBlock(), visitor->bytecodeOffset()));479 StackFrame(m_vm, visitor->callee().asCell(), visitor->codeBlock(), visitor->bytecodeOffset())); 480 480 } else { 481 481 m_results.append( 482 StackFrame(m_vm, visitor->callee()));482 StackFrame(m_vm, visitor->callee().asCell())); 483 483 } 484 484 … … 504 504 505 505 size_t framesCount = 0; 506 callFrame->iterate([&] (StackVisitor&) -> StackVisitor::Status {506 StackVisitor::visit(callFrame, &vm, [&] (StackVisitor&) -> StackVisitor::Status { 507 507 framesCount++; 508 508 return StackVisitor::Continue; … … 515 515 516 516 GetStackTraceFunctor functor(vm, results, framesToSkip, framesCount); 517 callFrame->iterate(functor);517 StackVisitor::visit(callFrame, &vm, functor); 518 518 ASSERT(results.size() == results.capacity()); 519 519 } … … 576 576 }; 577 577 578 ALWAYS_INLINE static void notifyDebuggerOfUnwinding(CallFrame* callFrame) 579 { 580 VM& vm = callFrame->vm(); 578 ALWAYS_INLINE static void notifyDebuggerOfUnwinding(VM& vm, CallFrame* callFrame) 579 { 581 580 auto catchScope = DECLARE_CATCH_SCOPE(vm); 582 if (Debugger* debugger = callFrame->vmEntryGlobalObject( )->debugger()) {581 if (Debugger* debugger = callFrame->vmEntryGlobalObject(vm)->debugger()) { 583 582 SuspendExceptionScope scope(&vm); 584 if (jsDynamicCast<JSFunction*>(vm, callFrame->jsCallee())) 583 if (callFrame->isAnyWasmCallee() 584 || (callFrame->callee().isCell() && callFrame->callee().asCell()->inherits(vm, JSFunction::info()))) 585 585 debugger->unwindEvent(callFrame); 586 586 else … … 592 592 class UnwindFunctor { 593 593 public: 594 UnwindFunctor(CallFrame*& callFrame, bool isTermination, CodeBlock*& codeBlock, HandlerInfo*& handler) 595 : m_callFrame(callFrame) 594 UnwindFunctor(VM& vm, CallFrame*& callFrame, bool isTermination, CodeBlock*& codeBlock, HandlerInfo*& handler) 595 : m_vm(vm) 596 , m_callFrame(callFrame) 596 597 , m_isTermination(isTermination) 597 598 , m_codeBlock(codeBlock) … … 615 616 } 616 617 617 notifyDebuggerOfUnwinding(m_ callFrame);618 notifyDebuggerOfUnwinding(m_vm, m_callFrame); 618 619 619 620 copyCalleeSavesToVMEntryFrameCalleeSavesBuffer(visitor); … … 635 636 return; 636 637 637 VM& vm = m_callFrame->vm();638 638 RegisterAtOffsetList* allCalleeSaves = VM::getAllCalleeSaveRegisterOffsets(); 639 639 RegisterSet dontCopyRegisters = RegisterSet::stackRegisters(); … … 641 641 642 642 unsigned registerCount = currentCalleeSaves->size(); 643 VMEntryRecord* record = vmEntryRecord( vm.topVMEntryFrame);643 VMEntryRecord* record = vmEntryRecord(m_vm.topVMEntryFrame); 644 644 for (unsigned i = 0; i < registerCount; i++) { 645 645 RegisterAtOffset currentEntry = currentCalleeSaves->at(i); … … 655 655 } 656 656 657 VM& m_vm; 657 658 CallFrame*& m_callFrame; 658 659 bool m_isTermination; … … 687 688 // Calculate an exception handler vPC, unwinding call frames as necessary. 688 689 HandlerInfo* handler = nullptr; 689 UnwindFunctor functor( callFrame, isTerminatedExecutionException(vm, exception), codeBlock, handler);690 callFrame->iterate(functor);690 UnwindFunctor functor(vm, callFrame, isTerminatedExecutionException(vm, exception), codeBlock, handler); 691 StackVisitor::visit(callFrame, &vm, functor); 691 692 if (!handler) 692 693 return nullptr; … … 695 696 } 696 697 697 void Interpreter::notifyDebuggerOfExceptionToBeThrown(CallFrame* callFrame, Exception* exception) 698 { 699 VM& vm = callFrame->vm(); 700 Debugger* debugger = callFrame->vmEntryGlobalObject()->debugger(); 698 void Interpreter::notifyDebuggerOfExceptionToBeThrown(VM& vm, CallFrame* callFrame, Exception* exception) 699 { 700 Debugger* debugger = callFrame->vmEntryGlobalObject(vm)->debugger(); 701 701 if (debugger && debugger->needsExceptionCallbacks() && !exception->didNotifyInspectorOfThrow()) { 702 702 // This code assumes that if the debugger is enabled then there is no inlining. … … 711 711 else { 712 712 GetCatchHandlerFunctor functor; 713 callFrame->iterate(functor);713 StackVisitor::visit(callFrame, &vm, functor); 714 714 HandlerInfo* handler = functor.handler(); 715 715 ASSERT(!handler || handler->isCatchHandler()); -
trunk/Source/JavaScriptCore/interpreter/Interpreter.h
r212692 r214905 139 139 140 140 NEVER_INLINE HandlerInfo* unwind(VM&, CallFrame*&, Exception*, UnwindStart); 141 void notifyDebuggerOfExceptionToBeThrown( CallFrame*, Exception*);141 void notifyDebuggerOfExceptionToBeThrown(VM&, CallFrame*, Exception*); 142 142 NEVER_INLINE void debug(CallFrame*, DebugHookType); 143 143 static JSString* stackTraceAsString(VM&, const Vector<StackFrame>&); -
trunk/Source/JavaScriptCore/interpreter/Register.h
r206525 r214905 77 77 int32_t& tag(); 78 78 79 void* pointer() const; 80 79 81 static Register withInt(int32_t i) 80 82 { … … 196 198 } 197 199 200 ALWAYS_INLINE void* Register::pointer() const 201 { 202 #if USE(JSVALUE64) 203 return u.encodedValue.ptr; 204 #else 205 return bitwise_cast<void*>(payload()); 206 #endif 207 } 208 198 209 ALWAYS_INLINE int32_t Register::payload() const 199 210 { -
trunk/Source/JavaScriptCore/interpreter/ShadowChicken.cpp
r211247 r214905 153 153 Vector<Frame> stackRightNow; 154 154 StackVisitor::visit( 155 exec, [&] (StackVisitor& visitor) -> StackVisitor::Status {155 exec, &vm, [&] (StackVisitor& visitor) -> StackVisitor::Status { 156 156 if (visitor->isInlinedFrame()) 157 157 return StackVisitor::Continue; … … 165 165 // FIXME: Make shadow chicken work with Wasm. 166 166 // https://bugs.webkit.org/show_bug.cgi?id=165441 167 stackRightNow.append(Frame(jsCast<JSObject*>(visitor->callee() ), visitor->callFrame(), isTailDeleted));167 stackRightNow.append(Frame(jsCast<JSObject*>(visitor->callee().asCell()), visitor->callFrame(), isTailDeleted)); 168 168 return StackVisitor::Continue; 169 169 }); … … 274 274 Vector<Frame> toPush; 275 275 StackVisitor::visit( 276 exec, [&] (StackVisitor& visitor) -> StackVisitor::Status {276 exec, &vm, [&] (StackVisitor& visitor) -> StackVisitor::Status { 277 277 if (visitor->isInlinedFrame()) { 278 278 // FIXME: Handle inlining. … … 307 307 RELEASE_ASSERT(scope->inherits(vm, JSScope::info())); 308 308 } 309 toPush.append(Frame(jsCast<JSObject*>(visitor->callee() ), callFrame, isTailDeleted, callFrame->thisValue(), scope, codeBlock, callFrame->callSiteIndex()));309 toPush.append(Frame(jsCast<JSObject*>(visitor->callee().asCell()), callFrame, isTailDeleted, callFrame->thisValue(), scope, codeBlock, callFrame->callSiteIndex())); 310 310 311 311 if (indexInLog < logCursorIndex -
trunk/Source/JavaScriptCore/interpreter/ShadowChickenInlines.h
r199076 r214905 34 34 void ShadowChicken::iterate(VM& vm, ExecState* exec, const Functor& functor) 35 35 { 36 DeferGC deferGC( exec->vm().heap);36 DeferGC deferGC(vm.heap); 37 37 38 38 update(vm, exec); -
trunk/Source/JavaScriptCore/interpreter/StackVisitor.cpp
r211247 r214905 32 32 #include "Interpreter.h" 33 33 #include "JSCInlines.h" 34 #include " JSWebAssemblyCallee.h"34 #include "WasmCallee.h" 35 35 #include <wtf/text/StringBuilder.h> 36 36 37 37 namespace JSC { 38 38 39 StackVisitor::StackVisitor(CallFrame* startFrame )39 StackVisitor::StackVisitor(CallFrame* startFrame, VM* vm) 40 40 { 41 41 m_frame.m_index = 0; … … 43 43 CallFrame* topFrame; 44 44 if (startFrame) { 45 m_frame.m_VMEntryFrame = startFrame->vm().topVMEntryFrame; 46 topFrame = startFrame->vm().topCallFrame; 45 ASSERT(vm); 46 m_frame.m_VMEntryFrame = vm->topVMEntryFrame; 47 topFrame = vm->topCallFrame; 47 48 48 49 if (topFrame && static_cast<void*>(m_frame.m_VMEntryFrame) == static_cast<void*>(topFrame)) { … … 104 105 } 105 106 106 if (callFrame-> callee()->isAnyWasmCallee(callFrame->vm())) {107 if (callFrame->isAnyWasmCallee()) { 107 108 readNonInlinedFrame(callFrame); 108 109 return; … … 156 157 m_frame.m_isWasmFrame = false; 157 158 158 JSCell*callee = callFrame->callee();159 CalleeBits callee = callFrame->callee(); 159 160 m_frame.m_callee = callee; 160 161 161 if (call ee->isAnyWasmCallee(*callee->vm())) {162 if (callFrame->isAnyWasmCallee()) { 162 163 m_frame.m_isWasmFrame = true; 163 164 m_frame.m_codeBlock = nullptr; … … 205 206 JSFunction* callee = inlineCallFrame->calleeForCallFrame(callFrame); 206 207 m_frame.m_callee = callee; 207 ASSERT( m_frame.callee());208 ASSERT(!!m_frame.callee().rawPtr()); 208 209 209 210 // The callerFrame just needs to be non-null to indicate that we … … 255 256 #if ENABLE(WEBASSEMBLY) 256 257 if (isWasmFrame()) { 257 if (JSCell* callee = this->callee()) { 258 if (JSWebAssemblyCallee* wasmCallee = jsDynamicCast<JSWebAssemblyCallee*>(*callee->vm(), callee)) 259 return wasmCallee->calleeSaveRegisters(); 260 // Other wasm callees (e.g, stubs) don't use callee save registers, so nothing needs 261 // to be restored for them. 258 if (callee().isCell()) { 259 RELEASE_ASSERT(isWebAssemblyToJSCallee(callee().asCell())); 260 return nullptr; 262 261 } 263 264 return nullptr;262 Wasm::Callee* wasmCallee = callee().asWasmCallee(); 263 return wasmCallee->calleeSaveRegisters(); 265 264 } 266 265 #endif // ENABLE(WEBASSEMBLY) … … 277 276 { 278 277 String traceLine; 279 JSCell* callee = this->callee();280 278 281 279 switch (codeType()) { … … 289 287 traceLine = ASCIILiteral("module code"); 290 288 break; 291 case CodeType::Native: 289 case CodeType::Native: { 290 JSCell* callee = this->callee().asCell(); 292 291 if (callee) 293 292 traceLine = getCalculatedDisplayName(callFrame()->vm(), jsCast<JSObject*>(callee)).impl(); 294 293 break; 295 case CodeType::Function: 296 traceLine = getCalculatedDisplayName(callFrame()->vm(), jsCast<JSObject*>(callee)).impl(); 294 } 295 case CodeType::Function: 296 traceLine = getCalculatedDisplayName(callFrame()->vm(), jsCast<JSObject*>(this->callee().asCell())).impl(); 297 297 break; 298 298 case CodeType::Global: … … 456 456 #endif 457 457 458 out.print(indent, "callee: ", RawPointer(callee() ), "\n");458 out.print(indent, "callee: ", RawPointer(callee().rawPtr()), "\n"); 459 459 out.print(indent, "returnPC: ", RawPointer(returnPC), "\n"); 460 460 out.print(indent, "callerFrame: ", RawPointer(callerFrame), "\n"); -
trunk/Source/JavaScriptCore/interpreter/StackVisitor.h
r209722 r214905 26 26 #pragma once 27 27 28 #include "CalleeBits.h" 28 29 #include "VMEntryRecord.h" 29 30 #include <functional> … … 63 64 bool callerIsVMEntryFrame() const { return m_callerIsVMEntryFrame; } 64 65 CallFrame* callerFrame() const { return m_callerFrame; } 65 JSCell*callee() const { return m_callee; }66 CalleeBits callee() const { return m_callee; } 66 67 CodeBlock* codeBlock() const { return m_codeBlock; } 67 68 unsigned bytecodeOffset() const { return m_bytecodeOffset; } … … 111 112 VMEntryFrame* m_CallerVMEntryFrame; 112 113 CallFrame* m_callerFrame; 113 JSCell*m_callee;114 CalleeBits m_callee; 114 115 CodeBlock* m_codeBlock; 115 116 size_t m_index; … … 131 132 132 133 template <typename Functor> 133 static void visit(CallFrame* startFrame, const Functor& functor)134 static void visit(CallFrame* startFrame, VM* vm, const Functor& functor) 134 135 { 135 StackVisitor visitor(startFrame );136 StackVisitor visitor(startFrame, vm); 136 137 while (visitor->callFrame()) { 137 138 Status status = functor(visitor); … … 147 148 148 149 private: 149 JS_EXPORT_PRIVATE StackVisitor(CallFrame* startFrame );150 JS_EXPORT_PRIVATE StackVisitor(CallFrame* startFrame, VM*); 150 151 151 152 JS_EXPORT_PRIVATE void gotoNextFrame();
Note:
See TracChangeset
for help on using the changeset viewer.