Exemple #1
0
BIF_RETTYPE code_is_module_native_1(BIF_ALIST_1)
{
    Module* modp;

    if (is_not_atom(BIF_ARG_1)) {
	BIF_ERROR(BIF_P, BADARG);
    }
    if ((modp = erts_get_module(BIF_ARG_1)) == NULL) {
	return am_undefined;
    }
    return (is_native(modp->code) ||
	    (modp->old_code != 0 && is_native(modp->old_code))) ?
		am_true : am_false;
}
Exemple #2
0
bool signal_from_native(void *ctx)
{
	ucontext_t *uc;

	uc = ctx;

	return is_native(uc->uc_mcontext.gregs[REG_IP]);
}
Exemple #3
0
BIF_RETTYPE code_is_module_native_1(BIF_ALIST_1)
{
    Module* modp;
    Eterm res;
    ErtsCodeIndex code_ix;

    if (is_not_atom(BIF_ARG_1)) {
	BIF_ERROR(BIF_P, BADARG);
    }
    code_ix = erts_active_code_ix();
    if ((modp = erts_get_module(BIF_ARG_1, code_ix)) == NULL) {
	return am_undefined;
    }
    erts_rlock_old_code(code_ix);
    res = ((modp->curr.code && is_native(modp->curr.code)) ||
	    (modp->old.code != 0 && is_native(modp->old.code))) ?
		am_true : am_false;
    erts_runlock_old_code(code_ix);
    return res;
}
Exemple #4
0
// ------------------------------------------------------------------
// ciMethod::build_method_data
//
// Generate new methodDataOop objects at compile time.
void ciMethod::build_method_data(methodHandle h_m) {
  EXCEPTION_CONTEXT;
  if (is_native() || is_abstract() || h_m()->is_accessor()) return;
  if (h_m()->method_data() == NULL) {
    methodOopDesc::build_interpreter_method_data(h_m, THREAD);
    if (HAS_PENDING_EXCEPTION) {
      CLEAR_PENDING_EXCEPTION;
    }
  }
  if (h_m()->method_data() != NULL) {
    _method_data = CURRENT_ENV->get_object(h_m()->method_data())->as_method_data();
    _method_data->load_data();
  } else {
    _method_data = CURRENT_ENV->get_empty_methodData();
  }
}
void AccessFlags::print_on(outputStream* st) const {
  if (is_public      ()) st->print("public "      );
  if (is_private     ()) st->print("private "     );
  if (is_protected   ()) st->print("protected "   );
  if (is_static      ()) st->print("static "      );
  if (is_final       ()) st->print("final "       );
  if (is_synchronized()) st->print("synchronized ");
  if (is_volatile    ()) st->print("volatile "    );
  if (is_transient   ()) st->print("transient "   );
  if (is_native      ()) st->print("native "      );
  if (is_interface   ()) st->print("interface "   );
  if (is_abstract    ()) st->print("abstract "    );
  if (is_strict      ()) st->print("strict "      );
  if (is_synthetic   ()) st->print("synthetic "   );
  if (is_old         ()) st->print("{old} "       );
  if (is_obsolete    ()) st->print("{obsolete} "  );
}
Exemple #6
0
static char *
purple_plugin_get_basename(const char *filename)
{
	const char *basename;
	const char *last_period;

	basename = strrchr(filename, G_DIR_SEPARATOR);
	if (basename != NULL)
		basename++;
	else
		basename = filename;

	if (is_native(basename) &&
		((last_period = strrchr(basename, '.')) != NULL))
			return g_strndup(basename, (last_period - basename));

	return g_strdup(basename);
}
// ------------------------------------------------------------------
// ciMethod::ensure_method_data
//
// Generate new MethodData* objects at compile time.
// Return true if allocation was successful or no MDO is required.
bool ciMethod::ensure_method_data(methodHandle h_m) {
  EXCEPTION_CONTEXT;
  if (is_native() || is_abstract() || h_m()->is_accessor()) {
    return true;
  }
  if (h_m()->method_data() == NULL) {
    Method::build_interpreter_method_data(h_m, THREAD);
    if (HAS_PENDING_EXCEPTION) {
      CLEAR_PENDING_EXCEPTION;
    }
  }
  if (h_m()->method_data() != NULL) {
    _method_data = CURRENT_ENV->get_method_data(h_m()->method_data());
    _method_data->load_data();
    return true;
  } else {
    _method_data = CURRENT_ENV->get_empty_methodData();
    return false;
  }
}
Exemple #8
0
void init_stack_trace_elem(struct stack_trace_elem *elem, unsigned long addr,
			   void *frame)
{
	elem->is_native = is_native(addr);
	elem->addr = addr;
	elem->frame = frame;

	if (elem->is_native)
		elem->type = STACK_TRACE_ELEM_TYPE_OTHER;
	else
		elem->type = STACK_TRACE_ELEM_TYPE_JIT;

	elem->vm_native_stack_index = vm_native_stack_index() - 1;
	elem->jni_stack_index = jni_stack_index() - 1;

	if (vm_native_stack_get_frame() == frame) {
		elem->type = STACK_TRACE_ELEM_TYPE_VM_NATIVE;
		elem->vm_native_stack_index--;
	}
}
Exemple #9
0
// ------------------------------------------------------------------
// ciFlags::print_member_flags
void ciFlags::print_member_flags(outputStream* st) {
  if (is_public()) {
    st->print("public");
  } else if (is_private()) {
    st->print("private");
  } else if (is_protected()) {
    st->print("protected");
  } else {
    st->print("DEFAULT_ACCESS");
  }

  if (is_static()) {
    st->print(",static");
  }
  if (is_final()) {
    st->print(",final");
  }
  if (is_synchronized()) {
    st->print(",synchronized");
  }
  if (is_volatile()) {
    st->print(",volatile");
  }
  if (is_transient()) {
    st->print(",transient");
  }
  if (is_native()) {
    st->print(",native");
  }
  if (is_abstract()) {
    st->print(",abstract");
  }
  if (is_strict()) {
    st->print(",strict");
  }

}
void Method::_set_nop()
{
    bool verbose = false;

    Global_Env *env = VM_Global_State::loader_env;
    if (get_name() != env->Init_String || get_descriptor() != env->VoidVoidDescriptor_String) {
        return;
    }

    if(is_native()) {
        return;
    }
    unsigned len = _byte_code_length;
    if(!len) {
        return;
    }
    U_8* bc = _byte_codes;
    Nop_Stack_State stack_state = NS_StackEmpty;
    if(verbose) {
        printf("=========== nop[%d]: %s.%s%s\n", len, get_class()->get_name()->bytes, get_name()->bytes, get_descriptor()->bytes);
    }
    for (unsigned idx = 0; idx < len; idx++) {
        U_8 b = bc[idx];
        if(verbose) {
            printf("\tbc[%d]=%d, state=%d\n", idx, b, stack_state);
        }
        if(b == 0xb1) {   // return
            if(verbose) {
                printf("+++++++ nop: %s.%s%s\n", get_class()->get_name()->bytes, get_name()->bytes, get_descriptor()->bytes);
            }
            _flags.is_nop = TRUE;
            return;
        }
        switch(stack_state) {
        case NS_StackEmpty:
            switch(b) {
            case 0x2a:  // aload_0
                stack_state = NS_ThisPushed;
                break;
            default:
                return;
            }
            break;
        case NS_ThisPushed:
            switch(b) {
            case 0x01:  // aconst_null
            case 0x03:  // iconst_0
                stack_state = NS_ThisAndZeroPushed;
                break;
            case 0xb7:  // invokespecial
                {
                    unsigned index = (bc[idx + 1] << 8) + bc[idx + 2];
                    if(verbose) {
                        printf("\tinvokespecial, index=%d\n", index);
                    }
                    Method_Handle mh = resolve_special_method_env(VM_Global_State::loader_env,
                                                                  get_class(),
                                                                  index, false);
                    Method *callee = (Method *)mh;
                    if(!callee) {
                        if(verbose) {
                            printf("\tinvokespecial, callee==null\n");
                        }
                        return;
                    }
                    if(callee == this) {
                        return;
                    }
                    if(verbose) {
                        printf("invokespecial: %s.%s%s\n", callee->get_class()->get_name()->bytes, callee->get_name()->bytes, callee->get_descriptor()->bytes);
                    }
                    if(!callee->is_nop()) {
                        return;
                    }
                    const char *descr = callee->get_descriptor()->bytes;
                    if(descr[1] != ')') {
                        return;
                    }
                    if(verbose) {
                        printf("invokespecial nop: %s.%s%s\n", callee->get_class()->get_name()->bytes, callee->get_name()->bytes, callee->get_descriptor()->bytes);
                    }
                }
                stack_state = NS_StackEmpty;
                idx += 2;
                break;
            default:
                return;
            }
            break;
        case NS_ThisAndZeroPushed:
            switch(b) {
            case 0xb5:  // putfield
                stack_state = NS_StackEmpty;
                if(verbose) {
                    printf("\tputfield\n");
                }
                idx += 2;
                break;
            default:
                return;
            }
            break;
        default:
            LDIE(57, "Unexpected stack state");
            return;
        }
    }
    LDIE(56, "should'nt get here");
} //Method::_set_nop
Exemple #11
0
/**
 * stack_trace_elem_next - sets @elem to the next call stack element.
 *
 * Returns 0 on success and -1 when bottom of stack is reached.
 */
int stack_trace_elem_next(struct stack_trace_elem *elem)
{
	unsigned long new_addr;
	unsigned long ret_addr;
	void *new_frame;

	/* If previous element was a JNI call then we move to the JNI
	 * caller's frame. We use the JNI stack_entry info to get the
	 * frame because we don't trust JNI methods's frame
	 * pointers. */
	if (elem->type == STACK_TRACE_ELEM_TYPE_JNI) {
		struct jni_stack_entry *tr =
			&jni_stack[elem->jni_stack_index--];

		new_frame = tr->caller_frame;
		new_addr = tr->return_address - 1;
		goto out;
	}

	if (elem->frame == NULL)
		return -1;

	/* Check if we hit the JNI interface frame */
	if (elem->jni_stack_index >= 0) {
		struct jni_stack_entry *tr =
			&jni_stack[elem->jni_stack_index];

		if (tr->vm_frame == elem->frame) {
			if (!tr->method) {
				/* This happens for JNI_OnLoad invocations */
				elem->type = STACK_TRACE_ELEM_TYPE_OTHER;
				elem->is_native = true;

				elem->addr  = tr->return_address;
				elem->frame = tr->caller_frame;
				return 0;
			}

			elem->type = STACK_TRACE_ELEM_TYPE_JNI;
			elem->is_native = false;

			elem->cu = tr->method->compilation_unit;
			elem->frame = NULL;

			struct native_stack_frame *vm_frame = tr->vm_frame;
			elem->addr = vm_frame->return_address;

			return 0;
		}
	}

	if (elem->is_native) {
		struct native_stack_frame *frame;

		frame = elem->frame;
		new_frame = frame->prev;
		ret_addr = frame->return_address;
	} else {
		struct jit_stack_frame *frame;

		frame = elem->frame;
		new_frame = frame->prev;
		ret_addr = frame->return_address;
	}

	/*
	 * We know only return addresses and we don't know the size of
	 * call instruction that was used. Therefore we don't know
	 * address of the call site beggining. We store address of the
	 * last byte of the call site instead which is enough
	 * information to obtain bytecode offset.
	 */
	new_addr = ret_addr - 1;

 out:
	/* Check if we hit the VM native caller frame */
	if (elem->vm_native_stack_index >= 0) {
		struct vm_native_stack_entry *tr =
			&vm_native_stack[elem->vm_native_stack_index];

		if (tr->stack_ptr - sizeof(struct native_stack_frame)
		    == new_frame)
		{
			elem->type = STACK_TRACE_ELEM_TYPE_VM_NATIVE;
			elem->is_native = true;
			new_addr = (unsigned long) tr->target;
			--elem->vm_native_stack_index;

			goto out2;
		}
	}

	/* Check if previous elemement was called from JIT trampoline. */
	if (elem->is_native && called_from_jit_trampoline(elem->frame)) {
		elem->type = STACK_TRACE_ELEM_TYPE_TRAMPOLINE;
		elem->is_native = true;
		goto out2;
	}

	elem->is_native = is_native(new_addr);

	if (elem->is_native)
		elem->type = STACK_TRACE_ELEM_TYPE_OTHER;
	else
		elem->type = STACK_TRACE_ELEM_TYPE_JIT;

 out2:
	elem->addr = new_addr;
	elem->frame = new_frame;

	return 0;
}
Exemple #12
0
/**
 * @param classRecord Record for method class.
 * @param methodRecord Calle's method record.
 * @param retAddr What the PC should be upon return.
 * @return true iff the stack frame was pushed.
 */
boolean dispatch_special (MethodRecord *methodRecord, byte *retAddr)
{
  #if DEBUG_METHODS
  int debug_ctr;
  #endif

  StackFrame *stackFrame;
  byte newStackFrameIndex;

  #if DEBUG_BYTECODE
  printf ("\n------ dispatch special - %d ------------------\n\n",
          methodRecord->signatureId);
  #endif

  #if DEBUG_METHODS
  printf ("dispatch_special: %d, %d\n", 
          (int) methodRecord, (int) retAddr);
  printf ("-- signature id = %d\n", methodRecord->signatureId);
  printf ("-- code offset  = %d\n", methodRecord->codeOffset);
  printf ("-- flags        = %d\n", methodRecord->mflags);
  printf ("-- num params   = %d\n", methodRecord->numParameters);
  printf ("-- stack ptr    = %d\n", (int) get_stack_ptr());
  printf ("-- max stack ptr= %d\n", (int) (currentThread->stackArray + (get_array_size(currentThread->stackArray))*2));
  #endif

  pop_words (methodRecord->numParameters);
  pc = retAddr;

  if (is_native (methodRecord))
  {
  #if DEBUG_METHODS
  printf ("-- native\n");
  #endif 
    dispatch_native (methodRecord->signatureId, get_stack_ptr() + 1);
    // Stack frame not pushed
    return false;
  }

  newStackFrameIndex = currentThread->stackFrameArraySize;
  
  if (newStackFrameIndex >= get_array_length((Object *) word2ptr (currentThread->stackFrameArray)))
  {
#if !FIXED_STACK_SIZE
  	// int len = get_array_length((Object *) word2ptr (currentThread->stackFrameArray));
  	int newlen = get_array_length((Object *) word2ptr (currentThread->stackFrameArray)) * 3 / 2;
  	JINT newStackFrameArray = JNULL;

	// Stack frames are indexed by a byte value so limit the size.  	
  	if (newlen <= 255)
  	{
  	    // increase the stack frame size
  		newStackFrameArray = ptr2word(reallocate_array(word2ptr(currentThread->stackFrameArray), newlen));
  	}
  	
  	// If can't allocate new stack, give in!
    if (newStackFrameArray == JNULL)
    {
#endif
      throw_exception (stackOverflowError);
      return false;
#if !FIXED_STACK_SIZE
    }
      	
  	// Assign new array
  	currentThread->stackFrameArray = newStackFrameArray;
#endif
  }
  
  if (newStackFrameIndex == 0)
  {
    // Assign NEW stack frame
    stackFrame = stackframe_array();
  }
  else
  {
    #if DEBUG_METHODS
    for (debug_ctr = 0; debug_ctr < methodRecord->numParameters; debug_ctr++)
      printf ("-- param[%d]    = %ld\n", debug_ctr, (long) get_stack_ptr()[debug_ctr+1]);  
    #endif

    // Save OLD stackFrame state
    stackFrame = stackframe_array() + (newStackFrameIndex - 1);
    update_stack_frame (stackFrame);
    // Push NEW stack frame
    stackFrame++;
  }
  // Increment size of stack frame array
  currentThread->stackFrameArraySize++;
  // Initialize rest of new stack frame
  stackFrame->methodRecord = methodRecord;
  stackFrame->monitor = null;
  stackFrame->localsBase = get_stack_ptr() + 1;
  // Initialize auxiliary global variables (registers)
  pc = get_code_ptr(methodRecord);

  #if DEBUG_METHODS
  printf ("pc set to 0x%X\n", (int) pc);
  #endif

  init_sp (stackFrame, methodRecord);
  update_constant_registers (stackFrame);
  
  //printf ("m %d stack = %d\n", (int) methodRecord->signatureId, (int) (localsBase - stack_array())); 
  
  // Check for stack overflow
  // (stackTop + methodRecord->maxOperands) >= (stack_array() + STACK_SIZE);
  if (is_stack_overflow (methodRecord))
  {
#if !FIXED_STACK_SIZE
    StackFrame *stackBase;
    int i;
    
    // Need at least this many bytes
    // int len = (int)(stackTop + methodRecord->maxOperands) - (int)(stack_array()) - HEADER_SIZE;
    
    // Need to compute new array size (as distinct from number of bytes in array).
  	int newlen = (((int)(stackTop + methodRecord->maxOperands) - (int)(stack_array()) - HEADER_SIZE + 1) / 4) * 3 / 2;
  	JINT newStackArray = ptr2word(reallocate_array(word2ptr(currentThread->stackArray), newlen));
  	
  	// If can't allocate new stack, give in!
    if (newStackArray == JNULL)
    {
#endif
      throw_exception (stackOverflowError);
      return false;
#if !FIXED_STACK_SIZE
    }
      	
    // Adjust pointers.
    newlen = newStackArray - currentThread->stackArray;
    stackBase = stackframe_array();
    stackTop = word2ptr(ptr2word(stackTop) + newlen);
    localsBase = word2ptr(ptr2word(localsBase) + newlen);
#if DEBUG_MEMORY
	printf("thread=%d, stackTop(%d), localsBase(%d)=%d\n", currentThread->threadId, (int)stackTop, (int)localsBase, (int)(*localsBase));
#endif
    for (i=currentThread->stackFrameArraySize-1;
         i >= 0;
         i--)
    {
    	stackBase[i].localsBase = word2ptr(ptr2word(stackBase[i].localsBase) + newlen);
   		stackBase[i].stackTop = word2ptr(ptr2word(stackBase[i].stackTop) + newlen);
#if DEBUG_MEMORY
	printf("stackBase[%d].localsBase(%d) = %d\n", i, (int)stackBase[i].localsBase, (int)(*stackBase[i].localsBase));
#endif
    }
    
  	// Assign new array
  	currentThread->stackArray = newStackArray;
#endif
  } 
  return true;
}
Exemple #13
0
/**
 * @param classRecord Record for method class.
 * @param methodRecord Calle's method record.
 * @param retAddr What the PC should be upon return.
 * @return true iff the stack frame was pushed.
 */
boolean dispatch_special (MethodRecord *methodRecord, byte *retAddr)
{
  /**
   * Note: This code is a little tricky, particularly when used with
   * a garbage collector. It manipulates the stack frame and in some cases
   * may need to perform memory allocation. In all cases we must take care
   * to ensure that if an allocation can be made then any live objects
   * on the stack must be below the current stack pointer.
   * In addition to the above we take great care so that this function can
   * be restarted (to allow us to wait for available memory). To enable this
   * we avoid making any commitments to changes to global state until both
   * stacks have been commited.
   */
  #if DEBUG_METHODS
  int debug_ctr;
  #endif

  Object *stackFrameArray;
  StackFrame *stackFrame;
  StackFrame *stackBase;
  int newStackFrameIndex;
  STACKWORD *newStackTop;
  #if DEBUG_BYTECODE
  printf("call method %d ret %x\n", methodRecord - get_method_table(get_class_record(0)), retAddr);
  printf ("\n------ dispatch special - %d ------------------\n\n",
          methodRecord->signatureId);
  #endif

  #if DEBUG_METHODS
  printf ("dispatch_special: %d, %d\n",
          (int) methodRecord, (int) retAddr);
  printf ("-- signature id = %d\n", methodRecord->signatureId);
  printf ("-- code offset  = %d\n", methodRecord->codeOffset);
  printf ("-- flags        = %d\n", methodRecord->mflags);
  printf ("-- num params   = %d\n", methodRecord->numParameters);
  //printf ("-- stack ptr    = %d\n", (int) get_stack_ptr());
  //printf ("-- max stack ptr= %d\n", (int) (currentThread->stackArray + (get_array_size(currentThread->stackArray))*2));
  #endif


  // First deal with the easy case of a native call...
  if (is_native (methodRecord))
  {
  #if DEBUG_METHODS
  printf ("-- native\n");
  #endif
    // WARNING: Once the instruction below has been executed we may have
    // references on the stack that are above the stack pointer. If a GC
    // gets run when in this state the reference may get collected as
    // grabage. This means that any native functions that take a reference
    // parameter and that may end up allocating memory *MUST* protect that
    // reference before calling the allocator...
    pop_words_cur (methodRecord->numParameters);
    switch(dispatch_native (methodRecord->signatureId, get_stack_ptr_cur() + 1))
    {
      case EXEC_RETRY:
        // Need to re-start the instruction, so reset the state of the stack
        curStackTop += methodRecord->numParameters;
        break;
      case EXEC_CONTINUE:
        // Normal completion return to the requested point.
        curPc = retAddr;
        break;
      case EXEC_RUN:
        // We are running new code, curPc will be set. Nothing to do.
        break;
      case EXEC_EXCEPTION:
        // An exception has been thrown. The PC will be set correctly and
        // the stack may have been adjusted...
        break;
    }
    // Stack frame not pushed
    return false;
  }
  // Now start to build the new stack frames. We start by placing the
  // the new stack pointer below any params. The params will become locals
  // in the new frame.
  newStackTop = get_stack_ptr_cur() - methodRecord->numParameters;

  newStackFrameIndex = (int)(byte)currentThread->stackFrameIndex;
  if (newStackFrameIndex >=  255)
  {
      throw_new_exception (JAVA_LANG_STACKOVERFLOWERROR);
      return false;
  }
  #if DEBUG_METHODS
  //for (debug_ctr = 0; debug_ctr < methodRecord->numParameters; debug_ctr++)
  //  printf ("-- param[%d]    = %ld\n", debug_ctr, (long) get_stack_ptr()[debug_ctr+1]);
  #endif
  stackFrameArray = ref2obj(currentThread->stackFrameArray);
  stackBase = (StackFrame *)array_start(stackFrameArray);
  // Setup OLD stackframe ready for return
  stackFrame = stackBase + (newStackFrameIndex);
  stackFrame->stackTop = newStackTop;
  stackFrame->pc = retAddr;
  // Push NEW stack frame
  // Increment size of stack frame array but do not commit to it until we have
  // completely built both new stacks.
  newStackFrameIndex++;
  stackFrame++;
  if (((byte *)stackFrame - (byte *)stackBase) >= get_array_length(stackFrameArray))
  {
#if FIXED_STACK_SIZE
    throw_new_exception (JAVA_LANG_STACKOVERFLOWERROR);
    return false;
#else
    if (expand_call_stack(currentThread) < 0)
      return false;
    stackFrame = (StackFrame *)array_start(currentThread->stackFrameArray) + newStackFrameIndex;
#endif
  }

  // Initialize rest of new stack frame
  stackFrame->methodRecord = methodRecord;
  stackFrame->monitor = null;
  stackFrame->localsBase = newStackTop + 1;
  // Allocate space for locals etc.
  newStackTop = init_sp(stackFrame, methodRecord);
  stackFrame->stackTop = newStackTop;
  currentThread->stackFrameIndex = newStackFrameIndex;

  // Check for stack overflow
  if (is_stack_overflow (newStackTop, methodRecord))
  {
#if FIXED_STACK_SIZE
    throw_new_exception (JAVA_LANG_STACKOVERFLOWERROR);
    return false;
#else

    if (expand_value_stack(currentThread, methodRecord->maxOperands+methodRecord->numLocals) < 0)
    {
      currentThread->stackFrameIndex--;
      return false;
    }
    // NOTE at this point newStackTop is no longer valid!
    newStackTop = stackFrame->stackTop;
#endif
  }
  // All set. So now we can finally commit to the new stack frames
  update_constant_registers (stackFrame);
  curStackTop = newStackTop;
  // and jump to the start of the new code
  curPc = get_code_ptr(methodRecord);
  return true;
}