Skip to content

Commit fa7dc18

Browse files
lavenzgmeta-codesync[bot]
authored andcommitted
Enable empty base alignment on Environment to make HV32 build on Windows
Summary: In Callable.h, we assert the invariant that the offset of `parentEnvironment_` and `size_` in `Environment` is the same as `parentEnvironment` and `size` in `SHEnvironment`, respectively. However, this is not always true with MSVC (Clang with enforce the same layout on Windows). `Environment` inherits from `VariableSizeRuntimeCell` and `TrailingObjects<Environment, GCHermesValue>` (with this order). With HV32 release mode, `VariableSizeRuntimeCell` has 4 bytes, `TrailingObjects<Environment, GCHermesValue>` has 0 bytes and has an `alignas(8)` specifier. The default memory layout is: 0: base class VariableSizeRuntimeCell 4: padding 8: parentEnvironment_ (if casting to TrailingObjects, the address is here) 12: size_ 16: trailing objects of GCHermesValue The reason is that MSVC does remove the empty class's storage (so `TrailingObjects` occupies 0 byte), but it still enforces that the empty base class still has a unique address. And due to the `alignas(8)` specifier, it has to add 4 padding bytes to make the address aligned to 8 bytes. With the `__declspec(empty_bases)` attribute, the memory layout is: 0: base class VariableSizeRuntimeCell 4: parentEnvironment_ 8: size_ 12: padding 16: trailing objects of GCHermesValue This is the same as SHEnvironment. Reviewed By: tmikov Differential Revision: D87686988 fbshipit-source-id: 014b2aeda05750c78e5d8a160249c43ce91ccf3f
1 parent e595577 commit fa7dc18

File tree

1 file changed

+18
-1
lines changed

1 file changed

+18
-1
lines changed

include/hermes/VM/Callable.h

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,24 @@ namespace hermes {
2424
namespace vm {
2525

2626
/// Environment storing all escaping variables for a function.
27-
class Environment final
27+
/// We need the `HERMES_EMPTY_BASES` attribute here because without it, MSVC
28+
/// or Clang on Windows will add 4 padding bytes before parentEnvironment_ under
29+
/// HV32 release mode (TrailingObjects<Environment, GCHermesValue> has
30+
/// an alignas(8) specifier), which causes different layout than SHEnvironment.
31+
/// Memory layout without HERMES_EMPTY_BASES, with HV32 release mode:
32+
/// 0: base class VariableSizeRuntimeCell
33+
/// 4: padding
34+
/// 8: parentEnvironment_
35+
/// 12: size_
36+
/// 16: trailing objects of GCHermesValue
37+
/// Memory layout with HERMES_EMPTY_BASES, with HV32 release mode:
38+
/// 0: base class VariableSizeRuntimeCell
39+
/// 4: parentEnvironment_
40+
/// 8: size_
41+
/// 12: padding
42+
/// 16: trailing objects of GChermesValue
43+
/// Once we upgrade to c++20, we should use [[no_unique_address]] here.
44+
class HERMES_EMPTY_BASES Environment final
2845
: public VariableSizeRuntimeCell,
2946
private llvh::TrailingObjects<Environment, GCHermesValue> {
3047
friend TrailingObjects;

0 commit comments

Comments
 (0)