JIT编译和DEP

2023-12-08

我正在考虑尝试一些 jit 编译(只是为了学习),并且让它跨平台工作会很好,因为我在家运行所有主要的三个(windows、os x、linux)。 考虑到这一点,我想知道是否有任何方法可以摆脱使用虚拟内存窗口函数来分配具有执行权限的内存。如果只使用 malloc 或 new 并将处理器指向这样的块,那就太好了。

有小费吗?


DEP 只是关闭内存中每个非代码页的执行权限。应用程序的代码被加载到有执行权限的内存中;并且有很多 JIT 可以在 Windows/Linux/MacOSX 中工作,即使 DEP 处于活动状态也是如此。这是因为有一种方法可以动态分配内存并设置所需的权限。

通常,不应使用普通的 malloc,因为权限是按页的。将分配的内存与页面对齐仍然是可能的,但需要付出一些开销。如果你不会使用malloc,一些自定义的内存管理(仅适用于可执行代码)。定制管理是一种常见的 JIT 方式。

Chromium 项目有一个解决方案,它使用 JavaScript V8 VM 的 JIT,并且是跨平台的。为了实现跨平台,所需的功能在多个文件中实现,并在编译时选择它们。

Linux:(chromium src/v8/src/platform-linux.cc)标志是 mmap() 的 PROT_EXEC。

void* OS::Allocate(const size_t requested,
                   size_t* allocated,
                   bool is_executable) {
  const size_t msize = RoundUp(requested, AllocateAlignment());
  int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
  void* addr = OS::GetRandomMmapAddr();
  void* mbase = mmap(addr, msize, prot, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
  if (mbase == MAP_FAILED) {
    /** handle error */
    return NULL;
  }
  *allocated = msize;
  UpdateAllocatedSpaceLimits(mbase, msize);
  return mbase;
}

Win32 (src/v8/src/platform-win32.cc): 标志是 VirtualAlloc 的 PAGE_EXECUTE_READWRITE

void* OS::Allocate(const size_t requested,
                   size_t* allocated,
                   bool is_executable) {
  // The address range used to randomize RWX allocations in OS::Allocate
  // Try not to map pages into the default range that windows loads DLLs
  // Use a multiple of 64k to prevent committing unused memory.
  // Note: This does not guarantee RWX regions will be within the
  // range kAllocationRandomAddressMin to kAllocationRandomAddressMax
#ifdef V8_HOST_ARCH_64_BIT
  static const intptr_t kAllocationRandomAddressMin = 0x0000000080000000;
  static const intptr_t kAllocationRandomAddressMax = 0x000003FFFFFF0000;
#else
  static const intptr_t kAllocationRandomAddressMin = 0x04000000;
  static const intptr_t kAllocationRandomAddressMax = 0x3FFF0000;
#endif

  // VirtualAlloc rounds allocated size to page size automatically.
  size_t msize = RoundUp(requested, static_cast<int>(GetPageSize()));
  intptr_t address = 0;

  // Windows XP SP2 allows Data Excution Prevention (DEP).
  int prot = is_executable ? PAGE_EXECUTE_READWRITE : PAGE_READWRITE;

  // For exectutable pages try and randomize the allocation address
  if (prot == PAGE_EXECUTE_READWRITE &&
      msize >= static_cast<size_t>(Page::kPageSize)) {
    address = (V8::RandomPrivate(Isolate::Current()) << kPageSizeBits)
      | kAllocationRandomAddressMin;
    address &= kAllocationRandomAddressMax;
  }

  LPVOID mbase = VirtualAlloc(reinterpret_cast<void *>(address),
                              msize,
                              MEM_COMMIT | MEM_RESERVE,
                              prot);
  if (mbase == NULL && address != 0)
    mbase = VirtualAlloc(NULL, msize, MEM_COMMIT | MEM_RESERVE, prot);

  if (mbase == NULL) {
    LOG(ISOLATE, StringEvent("OS::Allocate", "VirtualAlloc failed"));
    return NULL;
  }

  ASSERT(IsAligned(reinterpret_cast<size_t>(mbase), OS::AllocateAlignment()));

  *allocated = msize;
  UpdateAllocatedSpaceLimits(mbase, static_cast<int>(msize));
  return mbase;
}

MacOS (src/v8/src/platform-macos.cc):标志是 mmap 的 PROT_EXEC,就像 Linux 或其他 posix 一样。

void* OS::Allocate(const size_t requested,
                   size_t* allocated,
                   bool is_executable) {
  const size_t msize = RoundUp(requested, getpagesize());
  int prot = PROT_READ | PROT_WRITE | (is_executable ? PROT_EXEC : 0);
  void* mbase = mmap(OS::GetRandomMmapAddr(),
                     msize,
                     prot,
                     MAP_PRIVATE | MAP_ANON,
                     kMmapFd,
                     kMmapFdOffset);
  if (mbase == MAP_FAILED) {
    LOG(Isolate::Current(), StringEvent("OS::Allocate", "mmap failed"));
    return NULL;
  }
  *allocated = msize;
  UpdateAllocatedSpaceLimits(mbase, msize);
  return mbase;
}

我还想注意的是bcdedit.exe-like 方式应该仅用于非常旧的程序,它在内存中创建新的可执行代码,但不会在此页面上设置 Exec 属性。对于较新的程序,例如 firefox 或 Chrome/Chromium,或任何现代 JIT,DEP 应该处于活动状态,并且 JIT 将以细粒度的方式管理内存权限。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

JIT编译和DEP 的相关文章

  • 方法什么时候可以被 CLR 内联?

    我在应用程序中观察到很多 堆栈内省 代码 这些代码通常隐式依赖于它们的包含方法not被内联以确保其正确性 此类方法通常涉及调用 MethodBase GetCurrentMethod Assembly GetCallingAssembly
  • jit 会优化新对象吗

    我创建这个类是为了不可变并且具有流畅的 API public final class Message public final String email public final String escalationEmail public
  • 只需添加方法参数即可实现 10% 以上的性能提升(更精简的 jit 代码)

    注意 正确的答案必须超越复制 经过数百万次调用后 快速排序 1 肯定比快速排序 2 更快 除了这 1 个额外参数之外 快速排序 2 具有相同的代码 代码在帖子末尾 剧透 我还发现 jit 代码增加了 224 个字节 即使它实际上应该更简单
  • JIT可以做这个字段访问优化吗?

    免责声明 请不要就过早优化提出建议 我只是好奇 想象一下 我想确保字段引用的某些对象可以尽快被垃圾收集 我正在使用像这样的自制单链表 class BigData byte someBigArray BigData next private
  • 变量在 C# 版本 x64 中不递增

    有人可以向我解释为什么这段代码在 x86 平台上执行时运行良好 而在 x64 平台上执行时失败吗 结果 x86 调试 12345678910 x64 调试 12345678910 x86 版本 12345678910 x64 版本 1111
  • 类文件格式的最终​​变量

    Does class文件格式提供支持final关键字与变量一起使用吗 或者它只是从代码中推断出变量的有效最终性 然后 JIT 编译器基于它执行优化 Here https docs oracle com javase specs jvms s
  • 为什么 JVM 有最大内联深度?

    java有争论 XX MaxInlineLevel 默认值为 9 它控制内联嵌套调用的最大数量 为什么会有这样的限制 为什么基于频率和代码大小的常见启发法不足以让 JVM 自行决定内联的深度 这是由JitWatch https github
  • 智能 JVM 和 JIT 微优化

    随着时间的推移 Sun 的 JVM 和 JIT 已经变得相当智能 过去作为必要的微优化而成为常识的事情不再需要 因为它会为您处理好 例如 过去的情况是 您应该将所有可能的类标记为 Final 以便 JVM 内联尽可能多的代码 然而现在 JI
  • Python运行时:重新编译和重用C库

    我正在开发一个用于用户定义函数的数值分析的工具 这个想法是用 Python 制作一个方便的 UI 用户可以在其中输入 C 函数 然后按下按钮 并接收一些输出数据 计算可能需要几分钟或几小时 因此仅使用 Numpy 的性能是不可接受的 我尝试
  • 是否可以通过脚本禁用 Firefox JavaScript JIT?

    我们的网站有一个相当复杂的 JS 应用程序 该应用程序在最新的 Firefox 10 版本中失败 这是由于 JS 解释器中的一个错误导致变量返回 NULL 而实际上它们显然不是这样 此错误仅在 JIT 编译器处于活动状态时发生 而不是在禁用
  • 空闲后 JVM JIT 去优化

    我使用Java主要是为了编写宠物项目 这些项目大部分时间都是闲置的 闲置数小时 天后 响应时间增加到秒 最多 10 秒 然后慢慢减少到 200 300 毫秒 据我了解 发生这种情况是因为 JIT去优化 https www safariboo
  • JIT代码生成技术

    虚拟机如何动态生成本机机器代码并执行它 假设您可以弄清楚想要发出的本机机器操作码是什么 那么如何实际运行它呢 它是否像将助记符指令映射到二进制代码 将其填充到 char 指针中并将其转换为函数并执行一样hacky 或者您会生成一个临时共享库
  • 行为相同的条件检查的执行[重复]

    这个问题在这里已经有答案了 我回答了这个问题 https stackoverflow com questions 25234401 which is a better practice for if else condition 25234
  • ldstr 内部实现了 newobj 吗?

    众所周知 字符串是隐式实例化的 这意味着我们不必使用new为了获得对一个对象的引用 正因为如此 我一直相信框架正在处理这个问题 因此如果我这样做 我会得到相同的 IL String first new String new char a s
  • PyPy 明显慢于 CPython

    我一直在测试我制作的缓存系统 其目的是加速 Django Web 应用程序 它将所有内容存储在内存中 根据 cProfile 我的测试中的大部分时间都花在 QuerySet clone 内 结果证明效率非常低 考虑到实现 这实际上并不奇怪
  • JVM 是否会内联对象的实例变量和方法?

    假设我有一个非常紧密的内部循环 每次迭代都会访问和改变一个簿记对象 该对象存储有关算法的一些简单数据 并具有用于操作它的简单逻辑 簿记对象是私有的和最终的 并且它的所有方法都是私有的 最终的和 inline 下面是一个示例 Scala 语法
  • 静态方法是否会立即编译(JIT)?

    根据我的理解 CLR 编译器对实例方法和静态方法的处理方式相同 并且每当首次调用该方法时 IL 代码都会进行 JIT 编译 今天我和同事讨论了 他告诉我静态方法与实例方法的处理方式不同 即 静态方法在程序集加载到应用程序域后立即进行 JIT
  • 禁用 WerFault.exe/“应用程序已停止工作”崩溃对话框

    我有一个开发工具在启动时崩溃 我看不到它抛出的任何错误消息 也没有机会调试它 因为它显示了崩溃程序的 Windows 7 对话框 其中显示 Windows 正在检查寻求解决方案 我想让我的老派大屁股断言对话框回来 有一个大的 调试 按钮 我
  • 如何理解 EMCA 335 中有关“.locals init”的这些段落?

    来自 ECMA 335 I 12 4 1 方法调用 局部变量数组对于对象类型始终为 null 对于 保存对象的值类型中的字段 另外 如果 locals init设置后 局部变量数组初始化为0 对于整型类型为 0 0 对于浮点类型为 0 0
  • 找到对应的未经V8优化的JS代码源

    我尝试优化 node js 应用程序的性能 因此我正在分析 V8 的 JIT 编译器的行为 当通过运行应用程序时node trace deopt trace opt code comments print optcode 输出包含许多重复出

随机推荐

  • Haskell:更快的素数求和

    免责声明 我正在研究欧拉问题 9 我正在将一些相当大的数字相加 所有从 1 到 2 000 000 的素数 对这些素数求和需要很长时间 我正在使用 haskell 内置函数 sum as in sum listOfPrimes 还有其他更快
  • 具有相同 nuget 包的项目引用不同版本的程序集

    我快要疯了 我希望这是我忽略的事情 我正在经历间歇性的FileLoadExceptions 即使代码在部署之间发生变化 它们也会在部署后显示不更改任何程序集引用 看看最近的例子 我看到了FileLoadException due to Sy
  • 无需 GUI 即可运行 Electron

    我看到这个问题已被询问但该问题的上下文不同 因此没有与我的用例相关的答案 因此我提出一个新问题 我有一个基于 Electron 的 Web 服务器 它适用于不习惯命令行的网络开发新手 学生和艺术家 是的 这是一个很大的争论 但我被加州大学洛
  • 为什么我的应用程序无法在 Xcode 8 beta (8S128d) 中运行

    这是一个会影响许多应用程序的问题 可以在 Xcode 8 beta 8S128d 中找到 这是第一个 Beta 版 尽管它没有标记为 beta 1 问题出在 NSUserDefaults 上 它不起作用 这是代码 也许可以将其放入appli
  • Python:(显式)字符串参数会损害性能吗?

    假设某个函数总是获取一些它不使用的参数 def someFunc s do something not using s for example a 1 现在考虑这个电话 someFunc the unused string 它给出一个字符串
  • DbNull.Value 和 DbNull.Value.ToString() 之间的区别

    我想知道哪种用法是正确的 if string IsNullOrEmpty parentID cmd Parameters Add new SqlParameter ParentSesID parentID else cmd Paramete
  • 将用于生成电子邮件的 PHP 脚本转换为使用表单中的变量行

    我正在使用 PHP 脚本根据表单中的信息生成电子邮件 该表单的行数可变 我已将表单中每行的输入名称转换为数组 方法是添加 名称后 以便所有行中的数据都可用于生成电子邮件 但是 我不知道该怎么做是如何构建 PHP 以便它可以生成一封电子邮件
  • WinForms 文本框中的按钮

    WinForms 文本框是否具有任何可以在框末尾嵌入按钮的属性 就像 Chrome 地址框上的收藏夹按钮一样 我还在某些 Excel 表单中看到类似以下内容 EDIT 我按照 Hans Passant 的回答添加了一个点击事件处理程序 它似
  • 多个处理程序附加到一个事件:如何仅分离一个?

    在我正在处理的这个模块中 我有一个监听窗口中 调整大小 事件的监听器 每次运行模块时 我都需要检查是否已经有一个侦听器注册到该事件并将其分离 以避免出现不需要的行为 内存泄漏等 到目前为止一切顺利 但是 在我们正在开发的这个应用程序中 有可
  • Rails 多列上的唯一索引失败(sqlite3)

    我使用 Rails 设置了一个 HATBM 模型 其中包含一个用户表 一个组表和一个用于连接的 groups users 所有这些都使用scaffold 命令 现在我想添加一个迁移 以在表 groups users 的 group id 和
  • 为什么IDIV为-1会导致浮点异常?

    据我了解 idiv ebx将分裂edx eax 按顺序连接成 64 位值 与 32 位ebx 然而 当我尝试划分时0x00000000 0xfffffffb 0 和 5 与0xffffffff 1 我得到一个浮点异常 有人可以解释为什么吗
  • 将 PHP/MySQL 数据拆分为 3 列

    我需要使用从 MySQL 返回的数据在 PHP 中创建 3 个 HTML 列 我希望数据在所有 3 列之间均匀分配 我将如何做到这一点 你可以尝试做这样的事情 result mysql query SELECT value FROM tab
  • 查找行 NA 的数据框中的唯一性?

    我有一个如下所示的数据框 我想找到唯一的行 唯一性 但在这个数据中我有 NA 我喜欢如果一行中具有 NA 值的所有值与其他行相同 如行 1 2 5 我想忽略它 但如果不相同 如行 2 4 我喜欢保留它作为唯一行 例如 在第 1 2 和 6
  • 使用 JQuery 逐个字母淡入淡出

    我试图获取 all msg 的文本 并使用 hide 方法隐藏它 然后一次淡入一个字母 有一点延迟 这是我的代码 var all msg welcome msg function animate i all msg hide all msg
  • (Xcode 6 beta / Swift)performSegueWithIdentifier 在 segue 之前有延迟

    我刚刚第一次使用 Swift 和 Xcode 6 beta 学习 Ios 编程 我正在制作一个简单的测试应用程序 它应该调用 API 然后以编程方式转到不同的视图以显示检索到的信息 问题是segue 在我的委托方法中didReceiveAP
  • 当我“像 shell 脚本一样”运行 setuptools .egg 时,实际发生了什么?

    来自阅读本文档 我已经建立了一个关于命令内容的心理模型sh setuptools 0 6c11 py2 7 egg实际上确实如此 但它非常不完整 我仍然对某些方面感到困惑 我的思维模型是这样的 当发出这个命令时 egg 我认为它是一种巧妙处
  • jquery 的子字符串选择器?

    是否可以使用 jquery 仅选择字符串的一部分 例如我有一个文本 p Metuentes igitur idem latrones Lycaoniam magna parte campestrem p 所以现在如果用户搜索一个字符串 我希
  • C++17 静态内联成员的编译器错误

    我正在使用 Microsoft Visual Studio 2017 据我所知 它确实支持 C 17 静态内联类变量 我的问题是 如果我将所有成员保留为统一状态 它可以正常工作 但在初始化某些成员时会出现编译器错误 在以下示例中 inclu
  • 动态添加侦听器到 ajax 在 jQuery 中创建的内容

    我正在尝试获取单击的链接的 html 值 这些链接是使用 Ajax 动态创建的 所以我认为 bind 不会 工作 但我没有最新版本的 live div message click function var valueSelected thi
  • JIT编译和DEP

    我正在考虑尝试一些 jit 编译 只是为了学习 并且让它跨平台工作会很好 因为我在家运行所有主要的三个 windows os x linux 考虑到这一点 我想知道是否有任何方法可以摆脱使用虚拟内存窗口函数来分配具有执行权限的内存 如果只使