Home | History | Annotate | Download | only in arm
      1 /*
      2  * Copyright (C) 2008 The Android Open Source Project
      3  *
      4  * Licensed under the Apache License, Version 2.0 (the "License");
      5  * you may not use this file except in compliance with the License.
      6  * You may obtain a copy of the License at
      7  *
      8  *      http://www.apache.org/licenses/LICENSE-2.0
      9  *
     10  * Unless required by applicable law or agreed to in writing, software
     11  * distributed under the License is distributed on an "AS IS" BASIS,
     12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     13  * See the License for the specific language governing permissions and
     14  * limitations under the License.
     15  */
     16 /*
     17  * Target-specific optimization and run-time hints
     18  */
     19 
     20 
     21 #include "Dalvik.h"
     22 #include "libdex/DexClass.h"
     23 
     24 #include <stdlib.h>
     25 #include <stddef.h>
     26 #include <sys/stat.h>
     27 
     28 
     29 /*
     30  * The class loader will associate with each method a 32-bit info word
     31  * (jniArgInfo) to support JNI calls.  The high order 4 bits of this word
     32  * are the same for all targets, while the lower 28 are used for hints to
     33  * allow accelerated JNI bridge transfers.
     34  *
     35  * jniArgInfo (32-bit int) layout:
     36  *
     37  *    SRRRHHHH HHHHHHHH HHHHHHHH HHHHHHHH
     38  *
     39  *    S - if set, ignore the hints and do things the hard way (scan signature)
     40  *    R - return-type enumeration
     41  *    H - target-specific hints (see below for details)
     42  *
     43  * This function produces arm-specific hints - specifically a description
     44  * of padding required to keep all 64-bit parameters properly aligned.
     45  *
     46  * ARM JNI hint format
     47  *
     48  *       LLLL FFFFFFFF FFFFFFFF FFFFFFFF
     49  *
     50  *   L - number of double-words of storage required on the stack (0-30 words)
     51  *   F - pad flag -- if set, write a pad word to the stack before copying
     52  *       the next 32 bits
     53  *
     54  * If there are too many arguments to construct valid hints, this function will
     55  * return a result with the S bit set.
     56  */
     57 u4 dvmPlatformInvokeHints(const DexProto* proto)
     58 {
     59     const char* sig = dexProtoGetShorty(proto);
     60     int padFlags, jniHints;
     61     char sigByte;
     62     int stackOffset, padMask;
     63 
     64     stackOffset = padFlags = 0;
     65     padMask = 0x00000001;
     66 
     67     /* Skip past the return type */
     68     sig++;
     69 
     70     while (true) {
     71         sigByte = *(sig++);
     72 
     73         if (sigByte == '\0')
     74             break;
     75 
     76         if (sigByte == 'D' || sigByte == 'J') {
     77             if ((stackOffset & 1) != 0) {
     78                 padFlags |= padMask;
     79                 stackOffset++;
     80                 padMask <<= 1;
     81             }
     82             stackOffset += 2;
     83             padMask <<= 2;
     84         } else {
     85             stackOffset++;
     86             padMask <<= 1;
     87         }
     88     }
     89 
     90     jniHints = 0;
     91 
     92     if (stackOffset > DALVIK_JNI_COUNT_SHIFT) {
     93         /* too big for "fast" version */
     94         jniHints = DALVIK_JNI_NO_ARG_INFO;
     95     } else {
     96         assert((padFlags & (0xffffffff << DALVIK_JNI_COUNT_SHIFT)) == 0);
     97         stackOffset -= 2;           // r2/r3 holds first two items
     98         if (stackOffset < 0)
     99             stackOffset = 0;
    100         jniHints |= ((stackOffset+1) / 2) << DALVIK_JNI_COUNT_SHIFT;
    101         jniHints |= padFlags;
    102     }
    103 
    104     return jniHints;
    105 }
    106