Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make store-to-load forwarding work with FFI Pointers #53124

Closed
mkustermann opened this issue Aug 4, 2023 · 12 comments
Closed

Make store-to-load forwarding work with FFI Pointers #53124

mkustermann opened this issue Aug 4, 2023 · 12 comments
Labels
area-vm Use area-vm for VM related issues, including code coverage, FFI, and the AOT and JIT backends. type-performance Issue relates to performance or code size

Comments

@mkustermann
Copy link
Member

mkustermann commented Aug 4, 2023

Once we allow inlining force optimized functions (such as Pointer.fromAddress()) we seem to generate for this dart code

import 'dart:ffi';

main() {
  for (int i = 0; i < 10000; ++i) {
    foo();
  }
}

@pragma('vm:never-inline')
int foo() {
  return Pointer<Void>.fromAddress(0).address;
}

this flow graph

out/ReleaseX64/dart --print-flow-graph-optimized --print-flow-graph-filter=foo ffi.dart
*** BEGIN CFG
After AllocateRegisters
==== file:///.../sdk/ffi.dart_::_foo (RegularFunction)
  0: B0[graph]:0 {
      v0 <- Constant(#null) T{Null?}
      v1 <- Constant(#<optimized out>) T{Sentinel~}
      v2 <- Constant(#TypeArguments: (H116f861f) [Type: Void]) T{TypeArguments}
      v3 <- Constant(#0) [0, 0] T{_Smi}
      v32 <- Constant(#TypeArguments: (H39d2e3b4) [Type: Never]) T{TypeArguments}
      v35 <- UnboxedConstant(#0 int64) [0, 0] T{_Smi}
}
  2: B1[function entry]:2
  3:     ParallelMove rdx <- C
  4:     v28 <- AllocateObject:12(cls=Pointer, v32 T{TypeArguments}) T{Pointer}
  5:     ParallelMove rax <- rax, rcx <- C
  6:     StoreField(v28 . PointerBase.data = v35 T{_Smi} <int64>, NoStoreBarrier)
  8:     v18 <- LoadUntagged(v28 T{Pointer}, 8) T{*?}
 10:     v19 <- IntConverter(untagged->int64[tr], v18) T{int}
 12:     v20 <- BoxInt64(v19) T{int}
 14:     Return:18(v20 T{int})
*** END CFG

Instead it should just return a constant.

/cc @alexmarkov

@mkustermann mkustermann added area-vm Use area-vm for VM related issues, including code coverage, FFI, and the AOT and JIT backends. type-performance Issue relates to performance or code size labels Aug 4, 2023
@mkustermann
Copy link
Member Author

It does seem strange that we use StoreField to store but use LoadUntagged to load.

@mraleph
Copy link
Member

mraleph commented Aug 4, 2023

I think @ds84182 and @dcharkes were looking at this: #52510

I am not sure why this stalled.

@dcharkes
Copy link
Contributor

dcharkes commented Aug 7, 2023

I think @ds84182 and @dcharkes were looking at this: #52510

I am not sure why this stalled.

There are a bunch of test failures which haven't been triaged and addressed: https://dart-ci.firebaseapp.com/cl/305641/3.

@blaugold
Copy link
Contributor

blaugold commented Aug 7, 2023

I noticed that a few test failures had to do with Pointer.address. Shouldn't this Box instruction in the code generated for MethodRecognizer::kFfiGetAddress use kUnboxedIntPtr as the representation, since that is the representation of Slot::PointerBase_data?

@dcharkes
Copy link
Contributor

dcharkes commented Aug 7, 2023

Interesting, when merging the representations, we merge two non-equal representations:

  V(Pointer, UntaggedPointer, data_field, FfiIntPtr, FINAL)                    \
  V(TypedDataBase, UntaggedTypedDataBase, data_field, IntPtr, VAR)             \

to

  V(PointerBase, UntaggedPointerBase, data, IntPtr, VAR)

in https://dart-review.googlesource.com/c/sdk/+/231160 cc @alexmarkov

I don't believe we use the TypedData data field as int value, but we do use the Pointer data field as int value when doing .address. So the fix should be:

  V(PointerBase, UntaggedPointerBase, data, FfiIntPtr, VAR)

Though, that might have some unintended side effects.

@alexmarkov
Copy link
Contributor

@dcharkes What is the point of having distinct kUnboxedFfiIntPtr and kUnboxedIntPtr? Why kUnboxedFfiIntPtr is unsigned on 32-bit systems despite its name (IntPtr and not UintPtr)? Note that it could be more efficient to keep 32-bit addresses sign-extended when represented with Dart int, as they are more likely to fit into Smi range. #36370 looks related.

When changing the representation of a slot (such as Slot::PointerBase_data()) we need to make sure that all accesses to that slot (loads and stores) agree with its representation.

@dcharkes
Copy link
Contributor

dcharkes commented Aug 7, 2023

@dcharkes What is the point of having distinct kUnboxedFfiIntPtr and kUnboxedIntPtr? Why kUnboxedFfiIntPtr is unsigned on 32-bit systems despite its name (IntPtr and not UintPtr)?

// 'UnboxedFfiIntPtr' should be able to hold a pointer of the target word-size.
// On a 32-bit platform, it's an unsigned 32-bit int because it should be
// zero-extended to 64-bits, not sign-extended (pointers are inherently
// unsigned).

Introduced in https://dart-review.googlesource.com/c/sdk/+/94750 and https://dart-review.googlesource.com/c/sdk/+/94860.

There is already a TODO as you mention: #36370. I don't remember the motivation for #36370 (comment). @mkustermann do you? Is it that all pointers are always unsigned but we don't have a 64 bit unsigned representation? (e.g. https://dart-review.googlesource.com/c/sdk/+/195920 also defines unboxed-uword as unboxed-word.)

Note that it could be more efficient to keep 32-bit addresses sign-extended when represented with Dart int, as they are more likely to fit into Smi range.

The field is unboxed right? So it doesn't matter whether it's a Smi.

It would be a breaking change if we start showing 32 bit Pointer.addresses to users as signed.

To prevent a breaking change, we'd need to insert int-converter instructions at the loads and stores if we use kUnboxedIntPtr. This might be labour intensive, we have quite a lot of kUnboxedFfiIntPtr and kFfiIntPtr uses in the codebase.

When changing the representation of a slot (such as Slot::PointerBase_data()) we need to make sure that all accesses to that slot (loads and stores) agree with its representation.

Which might be less or more labour intensive. then covering all kUnboxedFfiIntPtr cases.

I noticed that a few test failures had to do with Pointer.address. Shouldn't this Box instruction in the code generated for MethodRecognizer::kFfiGetAddress use kUnboxedIntPtr as the representation, since that is the representation of Slot::PointerBase_data?

@blaugold Try adding IntConverter instructions in the places where you've removed ConvertUntaggedToUnboxed(kUnboxedIntPtr);. These are less places than completely removing the whole kUnboxedFfiIntPtr, and should enable you to move forward with the PR.

@blaugold
Copy link
Contributor

blaugold commented Aug 7, 2023

@blaugold Try adding IntConverter instructions in the places where you've removed ConvertUntaggedToUnboxed(kUnboxedIntPtr);. These are less places than completely removing the whole kUnboxedFfiIntPtr, and should enable you to move forward with the PR.

It's not my PR, I just took a look at the test failures and the code to see what might be going on. :) Hopefully @ds84182 is still interested in working on it.

@ds84182
Copy link
Contributor

ds84182 commented Aug 7, 2023

I'm still interested in working on it. I thought my latest commit fixed the issue but it seems like it hasn't :c

@mkustermann
Copy link
Member Author

There are a bunch of test failures which haven't been triaged and addressed: https://dart-ci.firebaseapp.com/cl/305641/3.

@dcharkes then we should diagnose and fix them :-)

I noticed that a few test failures had to do with Pointer.address. Shouldn't this Box instruction in the code generated for MethodRecognizer::kFfiGetAddress use kUnboxedIntPtr as the representation, since that is the representation of Slot::PointerBase_data?

I think @blaugold is spot on.

Here's a small reproduction for ia32 with the current state of the CL:

import 'dart:ffi';

import "package:expect/expect.dart";
import "package:ffi/ffi.dart";

void main() {
  while (true) {
    testPointerPointerArithmeticSizes();
  }
}

Pointer<Int64> int64Array = calloc(2);
void testPointerPointerArithmeticSizes() {
  Expect.equals(int64Array.address + 8, int64Array.elementAt(1).address);
}
% tools/build.py -nvh -d0 -mrelease -aia32 runtime
...
% out/ReleaseIA32/dart test.dart
Unhandled exception:
Expect.equals(expected: <-235902232>, actual: <4059065064>) fails.
...

This happens because once we have a 32-bit address and sign-extend it int32 to int64 do arithmetic and BoxInt64(), and once we truncate to u32 and then BoxUint32() it.

I think in the end it doesn't matter so much whether we represent C pointer addresses (i.e. Pointer<>.address) as sign-extended or not: Whenever we use it (e.g. to load/store memory, to pass to C code) we will only use the lower 32 bits. What matters is that we consistently go from the 32-bits in the Pointer object to the Dart int (64-bit) integer.

@blaugold
Copy link
Contributor

blaugold commented Sep 5, 2023

Try adding IntConverter instructions in the places where you've removed ConvertUntaggedToUnboxed(kUnboxedIntPtr);. These are less places than completely removing the whole kUnboxedFfiIntPtr, and should enable you to move forward with the PR.

@dcharkes Did you mean something like that?

diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
index d152d7b172b..7d69a63d4a9 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.cc
@@ -427,6 +427,18 @@ Fragment BaseFlowGraphBuilder::ConvertUnboxedToUntagged(
   return Fragment(converted);
 }
 
+Fragment BaseFlowGraphBuilder::ConvertUnboxedIntPtrToFfi() {
+  if (kUnboxedIntPtr == kUnboxedFfiIntPtr) {
+    return Fragment();
+  }
+  Value* value = Pop();
+  auto converted = new (Z) IntConverterInstr(kUnboxedIntPtr, kUnboxedFfiIntPtr,
+                                             value, DeoptId::kNone);
+  converted->mark_truncating();
+  Push(converted);
+  return Fragment(converted);
+}
+
 Fragment BaseFlowGraphBuilder::AddIntptrIntegers() {
   Value* right = Pop();
   Value* left = Pop();
diff --git a/runtime/vm/compiler/frontend/base_flow_graph_builder.h b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
index e6a13747769..198b4f814e9 100644
--- a/runtime/vm/compiler/frontend/base_flow_graph_builder.h
+++ b/runtime/vm/compiler/frontend/base_flow_graph_builder.h
@@ -185,6 +185,7 @@ class BaseFlowGraphBuilder {
   Fragment LoadUntagged(intptr_t offset);
   Fragment ConvertUntaggedToUnboxed(Representation to);
   Fragment ConvertUnboxedToUntagged(Representation from);
+  Fragment ConvertUnboxedIntPtrToFfi();
   Fragment UnboxSmiToIntptr();
   Fragment FloatToDouble();
   Fragment DoubleToFloat();
diff --git a/runtime/vm/compiler/frontend/kernel_to_il.cc b/runtime/vm/compiler/frontend/kernel_to_il.cc
index 9c31e4d6629..ec9f434862f 100644
--- a/runtime/vm/compiler/frontend/kernel_to_il.cc
+++ b/runtime/vm/compiler/frontend/kernel_to_il.cc
@@ -1381,6 +1381,7 @@ FlowGraph* FlowGraphBuilder::BuildGraphOfRecognizedMethod(
       body += LoadLocal(arg_value_not_null);
       if (kind == MethodRecognizer::kFfiStorePointer) {
         body += LoadNativeField(Slot::PointerBase_data());
+        body += ConvertUnboxedIntPtrToFfi();
       } else {
         // Avoid any unnecessary (and potentially deoptimizing) int
         // conversions by using the representation consumed by StoreIndexed.
@@ -1418,6 +1419,7 @@ FlowGraph* FlowGraphBuilder::BuildGraphOfRecognizedMethod(
       body += LoadLocal(parsed_function_->RawParameterVariable(0));  // Pointer.
       body += CheckNullOptimized(String::ZoneHandle(Z, function.name()));
       body += LoadNativeField(Slot::PointerBase_data());
+      body += ConvertUnboxedIntPtrToFfi();
       body += Box(kUnboxedFfiIntPtr);
     } break;
     case MethodRecognizer::kHas63BitSmis: {
@@ -4712,6 +4714,7 @@ Fragment FlowGraphBuilder::FfiConvertPrimitiveToNative(
   Fragment body;
   if (marshaller.IsPointer(arg_index)) {
     body += LoadNativeField(Slot::PointerBase_data());
+    body += ConvertUnboxedIntPtrToFfi();
   } else if (marshaller.IsHandle(arg_index)) {
     body += WrapHandle();
   } else {
@@ -4848,6 +4851,7 @@ FlowGraph* FlowGraphBuilder::BuildGraphOfFfiNative(const Function& function) {
                     ->context_variables()[0]));
 
   body += LoadNativeField(Slot::PointerBase_data());
+  body += ConvertUnboxedIntPtrToFfi();
 
   if (marshaller.PassTypedData()) {
     body += LoadLocal(typed_data);

@dcharkes
Copy link
Contributor

Currently, adding ConvertUnboxedIntPtrToFfi doesn't work, because our optimizer is a bit too eager and removes an intconverter from the chain in the example that Martin constructed:

    v22 <- LoadField(v3 T{Pointer} . PointerBase.data) T{int}
    v23 <- IntConverter(int32->uint32[tr], v22) T{int}
    v24 <- BoxUint32(v23) T{int}
    v74 <- UnboxInt64:34([guard-inputs], v11) T{int}
    v75 <- UnboxInt64:34([guard-inputs], v24 T{int}) T{int}
    v12 <- BinaryInt64Op:34(+ [tr], v75 T{int}, v74 T{_Smi}) T{int}

gets turned into

    v22 <- LoadField(v3 T{Pointer} . PointerBase.data) T{int}
    v23 <- IntConverter(int32->uint32[tr], v22) T{int}
    v82 <- IntConverter(int32->int64, v22) T{int}
    v12 <- BinaryInt64Op:34(+ [tr], v82 T{int}, v79 T{_Smi}) T{int}

I'll see what I can do to push this PR over the line.

copybara-service bot pushed a commit that referenced this issue Oct 13, 2023
…es."

This reverts commit 06d7a23.

Reason for revert: everything crashes on vm-aot-linux-debug-simarm_x64

Original change's description:
> [vm/compiler] Change MemoryCopy to also take untagged addresses.
>
> This CL adds the ability to pass the payload address of the source
> and destination directly to the MemoryCopy instruction as an untagged
> value.
>
> The new translation of the _TypedListBase._memMoveN methods use the new
> MemoryCopy constructor, retrieving the untagged value of the data field
> of both the source and destination. This way, if inlining exposes the
> allocation of the object from which the data field is being retrieved,
> then allocation sinking can remove the intermediate allocation if there
> are no escaping uses of the object.
>
> Since Pointer.asTypedList allocates such ExternalTypedData objects,
> this CL makes that method inlined if at all possible, which removes
> the intermediate allocation if the only use of the TypedData object
> is to call setRange for memory copying purposes.
>
> This CL also separates unboxed native slots into two groups: those
> that contain untagged addresses and those that do not. The former
> group now have the kUntagged representation, which mimics the old
> use of LoadUntagged for the PointerBase data field and also ensures
> that any arithmetic operations on untagged addresses must first be
> explicitly converted to an unboxed integer and then explicitly converted
> back to untagged before being stored in a slot that contains untagged
> addresses.
>
> When a unboxed native slot that contains untagged addresses is defined,
> the definition also includes a boolean which represents whether
> addresses that may be moved by the GC can be stored in this slot or not.
> The redundancy eliminator uses this to decide whether it is safe to
> eliminate a duplicate load, replace a load with the value originally
> stored in the slot, or lift a load out of a loop.
>
> In particular, the PointerBase data field may contain GC-moveable
> addresses, but only for internal TypedData objects and views, not
> for external TypedData objects or Pointers. To allow load optimizations
> involving the latter, the LoadField and StoreField instructions now
> take boolean flags for whether loads or stores from the slot are
> guaranteed to not be GC-moveable, to override the information from
> the slot argument.
>
> Notable benchmark changes on x64 (similar for other archs unless noted):
>
> JIT:
> * FfiMemory.PointerPointer: 250.7%
> * FfiStructCopy.Copy1Bytes: -26.73% (only x64)
> * FfiStructCopy.Copy32Bytes: -25.18% (only x64)
> * MemoryCopy.64.setRange.Pointer.Uint8: 19.36%
> * MemoryCopy.64.setRange.Pointer.Double: 18.96%
> * MemoryCopy.8.setRange.Pointer.Double: 17.59%
> * MemoryCopy.8.setRange.Pointer.Uint8: 19.46%
>
> AOT:
> * FfiMemory.PointerPointer: 323.5%
> * FfiStruct.FieldLoadStore: 483.3%
> * FileIO_readwrite_64kb: 15.39%
> * FileIO_readwrite_512kb (Intel Xeon): 46.22%
> * MemoryCopy.512.setRange.Pointer.Uint8: 35.20%
> * MemoryCopy.64.setRange.Pointer.Uint8: 55.40%
> * MemoryCopy.512.setRange.Pointer.Double: 29.45%
> * MemoryCopy.64.setRange.Pointer.Double: 60.37%
> * MemoryCopy.8.setRange.Pointer.Double: 59.54%
> * MemoryCopy.8.setRange.Pointer.Uint8: 55.40%
> * FfiStructCopy.Copy32Bytes: 398.3%
> * FfiStructCopy.Copy1Bytes: 1233%
>
> TEST=vm/dart/address_local_pointer, vm/dart/pointer_as_typed_list
>
> Issue: #42072
> Fixes: #53124
>
> Cq-Include-Trybots: luci.dart.try:vm-ffi-qemu-linux-release-arm-try,vm-eager-optimization-linux-release-x64-try,vm-linux-release-x64-try,vm-linux-debug-x64-try,vm-aot-linux-release-x64-try,vm-aot-linux-debug-x64-try
> Change-Id: I563e0bfac5b1ac6cf1111649934067c12891b631
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/324820
> Reviewed-by: Alexander Markov <alexmarkov@google.com>
> Commit-Queue: Tess Strickland <sstrickl@google.com>
> Reviewed-by: Martin Kustermann <kustermann@google.com>

Issue: #42072
Change-Id: I7c31434e01108487de69a32154bbefd1538c6f0f
Cq-Include-Trybots: luci.dart.try:vm-ffi-qemu-linux-release-arm-try,vm-eager-optimization-linux-release-x64-try,vm-linux-release-x64-try,vm-linux-debug-x64-try,vm-aot-linux-release-x64-try,vm-aot-linux-debug-x64-try
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/330523
Bot-Commit: Rubber Stamper <rubber-stamper@appspot.gserviceaccount.com>
Commit-Queue: Alexander Aprelev <aam@google.com>
Auto-Submit: Alexander Markov <alexmarkov@google.com>
Reviewed-by: Alexander Aprelev <aam@google.com>
copybara-service bot pushed a commit that referenced this issue Oct 17, 2023
…es."

This is a reland of commit 06d7a23

This version fixes an issue when a phi node has multiple inputs with
different unboxed integer representations. The original CL made a
change where only the representations were considered, not the range
of values for the Phi calculated by range analysis. The reland goes
back to the old behavior for this case.

Also fixes the new tests on 32-bit architectures.

Original change's description:
> [vm/compiler] Change MemoryCopy to also take untagged addresses.
>
> This CL adds the ability to pass the payload address of the source
> and destination directly to the MemoryCopy instruction as an untagged
> value.
>
> The new translation of the _TypedListBase._memMoveN methods use the new
> MemoryCopy constructor, retrieving the untagged value of the data field
> of both the source and destination. This way, if inlining exposes the
> allocation of the object from which the data field is being retrieved,
> then allocation sinking can remove the intermediate allocation if there
> are no escaping uses of the object.
>
> Since Pointer.asTypedList allocates such ExternalTypedData objects,
> this CL makes that method inlined if at all possible, which removes
> the intermediate allocation if the only use of the TypedData object
> is to call setRange for memory copying purposes.
>
> This CL also separates unboxed native slots into two groups: those
> that contain untagged addresses and those that do not. The former
> group now have the kUntagged representation, which mimics the old
> use of LoadUntagged for the PointerBase data field and also ensures
> that any arithmetic operations on untagged addresses must first be
> explicitly converted to an unboxed integer and then explicitly converted
> back to untagged before being stored in a slot that contains untagged
> addresses.
>
> When a unboxed native slot that contains untagged addresses is defined,
> the definition also includes a boolean which represents whether
> addresses that may be moved by the GC can be stored in this slot or not.
> The redundancy eliminator uses this to decide whether it is safe to
> eliminate a duplicate load, replace a load with the value originally
> stored in the slot, or lift a load out of a loop.
>
> In particular, the PointerBase data field may contain GC-moveable
> addresses, but only for internal TypedData objects and views, not
> for external TypedData objects or Pointers. To allow load optimizations
> involving the latter, the LoadField and StoreField instructions now
> take boolean flags for whether loads or stores from the slot are
> guaranteed to not be GC-moveable, to override the information from
> the slot argument.
>
> Notable benchmark changes on x64 (similar for other archs unless noted):
>
> JIT:
> * FfiMemory.PointerPointer: 250.7%
> * FfiStructCopy.Copy1Bytes: -26.73% (only x64)
> * FfiStructCopy.Copy32Bytes: -25.18% (only x64)
> * MemoryCopy.64.setRange.Pointer.Uint8: 19.36%
> * MemoryCopy.64.setRange.Pointer.Double: 18.96%
> * MemoryCopy.8.setRange.Pointer.Double: 17.59%
> * MemoryCopy.8.setRange.Pointer.Uint8: 19.46%
>
> AOT:
> * FfiMemory.PointerPointer: 323.5%
> * FfiStruct.FieldLoadStore: 483.3%
> * FileIO_readwrite_64kb: 15.39%
> * FileIO_readwrite_512kb (Intel Xeon): 46.22%
> * MemoryCopy.512.setRange.Pointer.Uint8: 35.20%
> * MemoryCopy.64.setRange.Pointer.Uint8: 55.40%
> * MemoryCopy.512.setRange.Pointer.Double: 29.45%
> * MemoryCopy.64.setRange.Pointer.Double: 60.37%
> * MemoryCopy.8.setRange.Pointer.Double: 59.54%
> * MemoryCopy.8.setRange.Pointer.Uint8: 55.40%
> * FfiStructCopy.Copy32Bytes: 398.3%
> * FfiStructCopy.Copy1Bytes: 1233%
>
> TEST=vm/dart/address_local_pointer, vm/dart/pointer_as_typed_list
>
> Issue: #42072
> Fixes: #53124
>
> Cq-Include-Trybots: luci.dart.try:vm-ffi-qemu-linux-release-arm-try,vm-eager-optimization-linux-release-x64-try,vm-linux-release-x64-try,vm-linux-debug-x64-try,vm-aot-linux-release-x64-try,vm-aot-linux-debug-x64-try
> Change-Id: I563e0bfac5b1ac6cf1111649934067c12891b631
> Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/324820
> Reviewed-by: Alexander Markov <alexmarkov@google.com>
> Commit-Queue: Tess Strickland <sstrickl@google.com>
> Reviewed-by: Martin Kustermann <kustermann@google.com>

TEST=vm/dart/address_local_pointer, vm/dart/pointer_as_typed_list

Issue: #42072
Fixes: #53124

Change-Id: Iabb0e910f12636d0ff51e711c8c9c98ad40e5811
Cq-Include-Trybots: luci.dart.try:vm-ffi-qemu-linux-release-arm-try,vm-eager-optimization-linux-release-x64-try,vm-linux-release-x64-try,vm-linux-debug-x64-try,vm-aot-linux-release-x64-try,vm-aot-linux-debug-x64-try,vm-aot-linux-release-simarm_x64-try,vm-aot-linux-debug-simarm_x64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/330600
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
Reviewed-by: Martin Kustermann <kustermann@google.com>
copybara-service bot pushed a commit that referenced this issue Oct 17, 2023
Missed a couple of LoadUntaggeds for PointerBase.data in the graph
intrinsifier during 4d1bdaa.

Creates slots for ExternalOneByteString.external_data and
ExternalTwoByteString.external_data and uses LoadField with those slots
instead of LoadUntagged.

TEST=ci

Issue: #42072
Fixes: #53124
Change-Id: I900281644c4c42ad303cc7a6121e4c8bb7852cfe
Cq-Include-Trybots: luci.dart.try:vm-aot-linux-release-simarm_x64-try,vm-aot-linux-release-x64-try
Reviewed-on: https://dart-review.googlesource.com/c/sdk/+/330787
Reviewed-by: Alexander Markov <alexmarkov@google.com>
Commit-Queue: Tess Strickland <sstrickl@google.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-vm Use area-vm for VM related issues, including code coverage, FFI, and the AOT and JIT backends. type-performance Issue relates to performance or code size
Projects
None yet
Development

No branches or pull requests

6 participants