常见问题

配置了虚拟化但是函数并未被虚拟化的原因以及解决办法

1.虚拟化后程序崩溃

请分析APP运行时的崩溃日志,通过日志信息确定具体崩溃的函数,取消勾选该函数,重新虚拟化该项目进行测试。

2.不支持ARM指令代码

针对包括ARM汇编指令的函数不支持虚拟化,请在筛选代码文件的时候忽略该类代码文件

3.存在线性条件判断时有可能不会虚拟化。比如:

void foo(int a) {
  switch (a) {
  case 0: puts("0");
  case 1: puts("1");
  case 2: puts("2");
  default:puts("O");
  }
}

或者

void foo(int a) {
  if (a == 0) puts("0");
  else if (a == 1) puts("1");
  else if (a == 2) puts("2");
  else puts("O");
}

这类代码不能虚拟化的原因是,编译器在优化的时候,可能会通过参数a动态计算出条件分支 的地址,然后使用寄存器跳转的方式执行选中的分支(arm64: BX X1,x86-64: JMP RDI), 出现这类情况时,KiwiVMCompiler工具链将自动过滤不做虚拟化。 解决办法是将分支判定改为非线性,让编译器无法优化,比如将上述的0,1,2改为0,3,8.

4.函数参数或者返回值是浮点数,或者调用了此类函数,将一定不会虚拟化。比如:

float foo(float a) {
  return a + 1.0f;
}

或者

int foo(int a) {
  return pow((float)a, 2);
}

解决办法是将重要代码提出单独成为一个函数,不在浮点数函数里面。

5.函数存在内敛汇编,将一定不会虚拟化。比如:

void foo(void) {
  __asm__("ret");
}

或者

int foo(int a) {
  return ntol(a);//会优化为一条汇编指令
}

解决办法是将产生汇编指令的代码提出单独成为一个函数。

6.函数返回值是大对象,将一定不会虚拟化。比如:

std::string foo(void) {
  return "foo";
}

解决办法:

void foo(std::string &result) {
  result = "foo";
}

7.函数参数存在非引用大对象,将一定不会虚拟化。比如:

void foo(std::string a) {
  puts(a.c_str());
}

解决办法:

void foo(std::string &a) {
  puts(a.c_str());
}

8.大量的浮点数运算,有可能不会被虚拟化。当前KiwiVM对浮点数支持比较有限。

解决办法是将重要代码提出单独成为一个函数,不在浮点数函数里面。

results matching ""

    No results matching ""