Exemplo n.º 1
0
	void CallStackNode::enumerateScopeChainAtoms(IScopeChainEnumerator& scb)
	{
		// First, get the "dynamic" portion of the scope chain, that is, the
		// part that is modified on-the-fly within the function.  This includes
		// activation objects for try/catch blocks and "with" clauses.

		if (m_info)
		{
            MethodSignaturep const ms = m_info->getMethodSignature();
            for (int i = (ms->max_scope() + ms->local_count() - 1), n = ms->local_count(); i >= n; --i)
            {
                Atom const scope = m_info->boxOneLocal(m_framep, i, m_traits);
                AvmAssert(atomKind(scope) != kUnusedAtomTag);
                // go ahead and call addScope, even if null or undefined.
                scb.addScope(scope);
            }
		}

		// Next, get the "static" portion of the scope chain, that is, the
		// part that is defined as part of the definition of the function.  This
		// includes the locals of any functions that enclose this one, and the "this"
		// object, if any.

		ScopeChain* scopeChain = m_env ? m_env->scope() : NULL;
		if (scopeChain) 
		{
			int scopeChainLength = scopeChain->getSize();
			for (int i = scopeChainLength - 1; i >= 0; --i)
			{
				Atom scope = scopeChain->getScope(i);
				if (AvmCore::isObject(scope))
				{
                    scb.addScope(scope);
				}
			}
		}
	}
Exemplo n.º 2
0
    /**
     * This function is called by JIT code if OSR has been requested
     * if (exec->current_osr != 0).  This function fills the JIT frame locals
     * to match the interpreter frame.  The JIT code looks like this:
     *
     *   if (*(&exec->current_osr)) {
     *     adjustFrame(...);
     *     goto loop_entry
     *   }
     */
    void OSR::adjustFrame(MethodFrame* jitMethodFrame, CallStackNode *callStack,
                             FramePtr jitFramePointer,  uint8_t *jitFrameTags)
    {
        MethodEnv* env = jitMethodFrame->env();
        BaseExecMgr* exec = BaseExecMgr::exec(env);
        OSR *osr = exec->current_osr;
        AvmAssert(osr && "should not have gotten here");
        Atom* interpFramePointer = osr->interp_frame;

        MethodSignaturep ms = env->method->getMethodSignature();
        int nLocals = ms->local_count();
        int stackBase = nLocals + ms->max_scope();
        FrameState* frameState = osr->jit_frame_state;
        int scopeTop = nLocals + frameState->scopeDepth;
        int stackTop = stackBase + frameState->stackDepth;

        // OSR has been requested.

#ifdef AVMPLUS_VERBOSE
        if (env->method->pool()->isVerbose(VB_interp)) {
            env->core()->console <<
                    "osr-adjust_frame " << env->method->method_id() <<
                    " " << env->method <<
                    " scopeTop=" << scopeTop <<
                    " stackTop=" << stackTop <<
                    "\n";
        }
#endif

        // Patch the JIT frame local variable slots and the scope slots in use to match the interpreter state.
        for (int i = 0; i < scopeTop; i++)
            unboxSlot(frameState, env, interpFramePointer, jitFramePointer, jitFrameTags, i);

        // zero out stack area for unused scopes:
        if (scopeTop < stackBase) {
            void* p = ((char*) jitFramePointer + (scopeTop << VARSHIFT(env->method)));
            size_t nbytes = (stackBase - scopeTop) << VARSHIFT(env->method);
            VMPI_memset(p, 0, nbytes);
        }

        // Patch operand stack slots:
        for (int i = stackBase; i < stackTop; i++)
            unboxSlot(frameState, env, interpFramePointer, jitFramePointer, jitFrameTags, i);

        MethodFrame *interpreterMethodFrame = jitMethodFrame->next;
        jitMethodFrame->dxns = interpreterMethodFrame->dxns;
        jitMethodFrame->next = interpreterMethodFrame->next;

        // Clean up non-local OSR parameterization data:
        mmfx_delete(frameState);
        exec->current_osr = NULL;

#ifdef DEBUGGER
        // Call debugEnter if necessary, since the jit code won't.
        // We can safely pass NULL for &eip here, because OSR is disabled
        // for methods with catch blocks.
        if (callStack)
            env->debugEnter(jitFrameTags, callStack, jitFramePointer, NULL);
#else
        (void) callStack;
#endif
    }
Exemplo n.º 3
0
    /**
     * This function detects if OSR has been requested or if this is a
     * subsequent normal call.  In the latter case it has no side effect and
     * returns false and control flow is supposed to proceed normally.
     * If OSR is in the works, then it fills the JIT frame locals to match the
     * interpreter frame.  Then it returns true, which indicates to the
     * generated code to jump to the OSR entry point.
     *
     * The JIT code looks like this:
     *
     *   if (adjust_frame(...))
     *     goto loop_entry
     */
    int32_t OSR::adjustFrame(MethodFrame* jitMethodFrame,
                             CallStackNode *callStack,
                             FramePtr jitFramePointer,
                             uint8_t *jitFrameTags)
    {
        MethodEnv* env = jitMethodFrame->env();
        BaseExecMgr* exec = BaseExecMgr::exec(env);
        OSR *osr = exec->current_osr;
        if (!osr) {
            // No OSR has been requested.
            // We are at the beginning of a normal AS method call.
            // Indicate proceeding with normal control flow.
            return 0;
        }
        Atom* interpFramePointer = osr->interp_frame;

        MethodSignaturep ms = env->method->getMethodSignature();
        int nLocals = ms->local_count();
        int stackBase = nLocals + ms->max_scope();
        FrameState* frameState = osr->jit_frame_state;
        int scopeTop = nLocals + frameState->scopeDepth;
        int stackTop = stackBase + frameState->stackDepth;

        // OSR has been requested.

#ifdef AVMPLUS_VERBOSE
        if (env->method->pool()->isVerbose(VB_interp)) {
            env->core()->console <<
                    "osr-adjust_frame " << env->method->method_id() <<
                    " " << env->method <<
                    " scopeTop=" << scopeTop <<
                    " stackTop=" << stackTop <<
                    "\n";
        }
#endif

        // Patch the JIT frame local variable slots and the scope slots in use to match the interpreter state.
        for (int i = 0; i < scopeTop; i++)
            unboxSlot(frameState, env, interpFramePointer, jitFramePointer, jitFrameTags, i);

        // zero out stack area for unused scopes:
        if (scopeTop < stackBase) {
            void* p = ((char*) jitFramePointer + scopeTop * VARSIZE);
            size_t nbytes = (stackBase - scopeTop) * VARSIZE;
            VMPI_memset(p, 0, nbytes);
        }

        // Patch operand stack slots:
        for (int i = stackBase; i < stackTop; i++)
            unboxSlot(frameState, env, interpFramePointer, jitFramePointer, jitFrameTags, i);

        MethodFrame *interpreterMethodFrame = jitMethodFrame->next;
        jitMethodFrame->dxns = interpreterMethodFrame->dxns;
        jitMethodFrame->next = interpreterMethodFrame->next;

        // Clean up non-local OSR parameterization data:
        mmfx_delete(frameState);
        exec->current_osr = NULL;

#ifdef DEBUGGER
        // Call debugEnter if necessary, since the jit code won't.
        // We can safely pass NULL for &eip here, because OSR is disabled
        // for methods with catch blocks.
        if (callStack)
            env->debugEnter(jitFrameTags, callStack, jitFramePointer, NULL);
#else
        (void) callStack;
#endif

        // Indicate taking a shortcut from the call site
        // to the OSR entry point instead of normal control flow:
        return 1;
    }