Skip to content

[SE-0101] Implement: Reconfiguring sizeof and related functions into a unified MemoryLayout struct - Part 1 #3854

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

Merged
merged 3 commits into from
Jul 29, 2016

Conversation

rintaro
Copy link
Member

@rintaro rintaro commented Jul 29, 2016

Implement SE-0101

Currently sizeof family functions are simply marked as deprecated.

  1. Merge this PR.
  2. Merge PRs to other repos.
  3. Mark obsoleted functions as unavailable, and turn on migration fix-it.

Still need more test case for migration support.

CC:
@tkremenek
Are you still accepting new implementation?

@gribozavr
Could you review stdlib part? Added stdlib/public/core/MemoryLayout.swift
@jrose-apple, @DougGregor
Could you review fix-it part? Removed from this PR. I will split them into another PR.


Before merging this pull request to apple/swift repository:

  • Test pull request on Swift continuous integration.

Triggering Swift CI

The swift-ci is triggered by writing a comment on this PR addressed to the GitHub user @swift-ci. Different tests will run depending on the specific comment that you use. The currently available comments are:

Smoke Testing

Platform Comment
All supported platforms @swift-ci Please smoke test
All supported platforms @swift-ci Please smoke test and merge
OS X platform @swift-ci Please smoke test OS X platform
Linux platform @swift-ci Please smoke test Linux platform

A smoke test on macOS does the following:

  1. Builds the compiler incrementally.
  2. Builds the standard library only for macOS. Simulator standard libraries and
    device standard libraries are not built.
  3. lldb is not built.
  4. The test and validation-test targets are run only for macOS. The optimized
    version of these tests are not run.

A smoke test on Linux does the following:

  1. Builds the compiler incrementally.
  2. Builds the standard library incrementally.
  3. lldb is built incrementally.
  4. The swift test and validation-test targets are run. The optimized version of these
    tests are not run.
  5. lldb is tested.

Validation Testing

Platform Comment
All supported platforms @swift-ci Please test
All supported platforms @swift-ci Please test and merge
OS X platform @swift-ci Please test OS X platform
OS X platform @swift-ci Please benchmark
Linux platform @swift-ci Please test Linux platform

Lint Testing

Language Comment
Python @swift-ci Please Python lint

Note: Only members of the Apple organization can trigger swift-ci.

@rintaro rintaro changed the title [WIP][SE-101] Implement: Reconfiguring sizeof and related functions into a unified MemoryLayout struct [WIP][SE-0101] Implement: Reconfiguring sizeof and related functions into a unified MemoryLayout struct Jul 29, 2016
@rintaro rintaro force-pushed the SE-0101-memorylayout branch from 373e7ff to 924a504 Compare July 29, 2016 05:42
@gribozavr
Copy link
Contributor

@rintaro To get CI coverage and avoid lockstep issues, you could add old declarations as deprecated. Then we can independently land fixes to swift-corelibs-* and then remove the deprecated syntax. What do you think?

@rintaro
Copy link
Member Author

rintaro commented Jul 29, 2016

@gribozavr OK, I'll try it.

@@ -114,7 +114,7 @@ public struct DispatchData : RandomAccessCollection, _ObjectiveCBridgeable {
///
/// - parameter buffer: The buffer of bytes to append. The size is calculated from `SourceType` and `buffer.count`.
public mutating func append<SourceType>(_ buffer : UnsafeBufferPointer<SourceType>) {
self.append(UnsafePointer(buffer.baseAddress!), count: buffer.count * sizeof(SourceType.self))
self.append(UnsafePointer(buffer.baseAddress!), count: buffer.count * MemoryLayout<SourceType>.size)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This code was changed in the master branch, would you mind rebasing?

Also, could you change sizeof to strideof? Using sizeof here can cause bugs.

@rintaro rintaro force-pushed the SE-0101-memorylayout branch from 924a504 to 373e7ff Compare July 29, 2016 06:09
public static func of(_ candidate : @autoclosure () -> T) -> MemoryLayout<T>.Type {
return MemoryLayout.init(candidate).dynamicType
}
}
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can implement it simpler:

extension MemoryLayout {
  public static func of(_ candidate: @autoclosure () -> T) -> MemoryLayout<T>.Type {
    return MemoryLayout<T>.self
  }
}

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just copy pasted it from the proposal. 😓
I'll test it.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It worked.

@gribozavr
Copy link
Contributor

@rintaro Thank you! Let's see if we can get a CI run:

@swift-ci Please test OS X platform

@gribozavr
Copy link
Contributor

I reviewed the patch, LGTM as written, but I will do another pass after you rebase.

@rudkx
Copy link
Contributor

rudkx commented Jul 29, 2016

MiscDiagnostics.cpp changes LGTM!

buffer.baseAddress!.withMemoryRebound(to: UInt8.self, capacity: buffer.count * strideof(SourceType.self)) {
self.append($0, count: buffer.count * sizeof(SourceType.self))
buffer.baseAddress!.withMemoryRebound(to: UInt8.self, capacity: buffer.count * MemoryLayout<SourceType>.stride) {
self.append($0, count: buffer.count * MemoryLayout<SourceType>.stride)
Copy link
Member Author

@rintaro rintaro Jul 29, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@gribozavr You didn't mention this sizeof -> stride change. This should be .size?
This was introduced in recent change.(https://github.com/apple/swift/blob/0b75ee975e55ffa7c8a69a0f076f33ff82b64f44/stdlib/public/SDK/Dispatch/Data.swift#L118) @atrick ?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is supposed to be .stride on both modified lines.
I forgot to change the original code to strideof() and hadn't pushed my fix yet.

Copy link
Member Author

@rintaro rintaro Jul 29, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@atrick
Thank you! If you have more fix, feel free to push them first.
I'd happy to rebase on it.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I won't push my fix, it makes more sense as part of your PR. Thanks.

@rintaro rintaro force-pushed the SE-0101-memorylayout branch from 2128555 to ae977ab Compare July 29, 2016 07:38
@gribozavr
Copy link
Contributor

@swift-ci Please test

@xwu
Copy link
Collaborator

xwu commented Jul 29, 2016

IIUC, the core team decision for SE-0101 was that MemoryLayout should be implemented as an enum with no cases. I imagine that this also means the ofValue variants are not to be included (a slightly bigger migration task).

@rintaro
Copy link
Member Author

rintaro commented Jul 29, 2016

@xwu Sorry, I didn't read the Rationale, and the proposal itself carefully..
I'll read the evolution thread later. But, sadly, I'm busy for a few hours from now :(

@rintaro
Copy link
Member Author

rintaro commented Jul 29, 2016

As for struct => enum, no problem.
As for .of(value), I think we can remove it.
I defer the decision to the core team. @gribozavr, @dabrahams ?

If we decide to drop it, the implementation of migration fix-it cannot be fully implemented, or will be very complicated.

Contrived example here:

func fn<S: Sequence>(s: S) {
  var i = s.makeIterator()
  let size = sizeofValue(i.next()!)
  // Compare:
  // let size = MemoryLayout<S.Iterator.Element>.size; _ = i.next()!
  // let size = MemoryLayout.of(i.next()!).size

We have to actually look into the type of the value.
And, in case of reading the value has side effects, we have to evaluate and discard the result.
I assume we can implement that, but I'm not sure I can.
And typically, we prefer minimally modify the source (by fix-it).


extension MemoryLayout {
@_transparent
public static func of(_ candidate : @autoclosure () -> T) -> MemoryLayout<T>.Type {
Copy link
Member Author

@rintaro rintaro Jul 29, 2016

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

candidate is not needed here.

@gribozavr
Copy link
Contributor

@rintaro Thanks again for the implementation. I just checked with @dabrahams and he said that the core team did not approve the .of(_:) API. But, seeing the uses of it in the library, we think it would be a regression for our code to remove it, so we ask you to to keep it as a public @testable function with the name MemoryLayout._ofInstance(_:), and maybe re-open the discussion about adding it back as a public API.

You should keep the uses of this underscored _ofInstance() function in the swift.git repo, but eliminate the uses of it from other repos (hopefully, there are not so many of them as in the primary repo).

Does this sound good?

Sorry for not providing this feedback earlier!

@rintaro
Copy link
Member Author

rintaro commented Jul 29, 2016

@gribozavr no problem 👍 I'll update the PR soon.

@rintaro
Copy link
Member Author

rintaro commented Jul 29, 2016

@gribozavr Can I split the changes to lib/Sema/MiscDiagnostics.cpp into another PR?
I think that should be applied later.

@gribozavr
Copy link
Contributor

@rintaro Absolutely!

rintaro added 3 commits July 30, 2016 03:09
…MemoryLayout struct

As of now:

* old APIs are just marked as `deprecated` not `unavaiable`. To make it
  easier to co-operate with other toolchain repos.
* Value variant of API is implemented as public @Private
  `_ofInstance(_:)`.
@rintaro rintaro force-pushed the SE-0101-memorylayout branch from 9e9149f to 06603c1 Compare July 29, 2016 18:11
@rintaro rintaro changed the title [WIP][SE-0101] Implement: Reconfiguring sizeof and related functions into a unified MemoryLayout struct [SE-0101] Implement: Reconfiguring sizeof and related functions into a unified MemoryLayout struct Jul 29, 2016
@rintaro rintaro changed the title [SE-0101] Implement: Reconfiguring sizeof and related functions into a unified MemoryLayout struct [SE-0101] Implement: Reconfiguring sizeof and related functions into a unified MemoryLayout struct - Part 1 Jul 29, 2016
@rintaro
Copy link
Member Author

rintaro commented Jul 29, 2016

@gribozavr Updated.

@rintaro
Copy link
Member Author

rintaro commented Jul 29, 2016

@swift-ci Please smoke test

@xwu
Copy link
Collaborator

xwu commented Jul 29, 2016

Since _ofInstance is internal API, and as you point out @autoclosure actually changes the semantics, perhaps safest to restore the original ofValue semantics for _ofInstance so that all side effects are still triggered?

@rintaro
Copy link
Member Author

rintaro commented Jul 29, 2016

Since all of current usages of _ofInstance(_:) in this repo has no side effects, we can keep @autoclosure. But I don't know which is faster. Let's try

@swift-ci Please benchmark

@swift-ci
Copy link
Contributor

Build comment file:


@gribozavr
Copy link
Contributor

@rintaro There should be no difference with and without autoclosure. I will look at the generated code right now.

@@ -149,7 +149,7 @@ public struct DispatchData : RandomAccessCollection, _ObjectiveCBridgeable {

/// Copy the contents of the data into a buffer.
///
/// This function copies the bytes in `range` from the data into the buffer. If the count of the `range` is greater than `sizeof(DestinationType) * buffer.count` then the first N bytes will be copied into the buffer.
/// This function copies the bytes in `range` from the data into the buffer. If the count of the `range` is greater than `MemoryLayout<DestinationType>.size * buffer.count` then the first N bytes will be copied into the buffer.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

.stride. Please make this change as a separate commit so that it does not invalidate the CI results. (This is comment-only, so it does not matter for the purposes of CI.)

@gribozavr
Copy link
Contributor

@rintaro The code as it is now, with the autoclosure, is optimal. The optimizer eliminates the closure. Let's keep the autoclosure.

@swift-ci
Copy link
Contributor

Build comment file:


@gribozavr
Copy link
Contributor

@swift-ci Please test

@gribozavr
Copy link
Contributor

The changes look good to me, but I want to get a full CI run, with all the platforms and downstream projects.

@rintaro Please submit the C++ code changes and the comment change I requested as separate pull requests, thank you!

@gribozavr
Copy link
Contributor

Linux failures are unrelated. Merging.

@rintaro
Copy link
Member Author

rintaro commented Aug 2, 2016

@gribozavr Can I ask you to update CHANGELOG.md?
Because I'm not good at writing in English.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

6 participants