Remove the unused env_init field from class blocks#13193
Conversation
|
Out of curiosity: did `git blame` help in any way to understand how we
endedup in this situation?
|
|
|
No worries and thanks a lot for the additional bit of context!
Who knows, maybe @garrigue will remember, even more than 20 years
later!?
|
|
Indeed, I am the one who introduced |
|
OK, looking at the code it is clear that This said, objects are not well tested by the testsuite, so only relying on it for correctness is rather risky. module F (X:sig val x: int end) = struct
class c = object method x = X.x end
end
module M = F(struct let x = 3 end) |
|
Independently of the testing, if you remove the explanation of |
|
I ran a test with functors (extended from the one you provided): module F (X:sig val x: int end) = struct
class c = object method x = X.x end
end
module M1 = F(struct let x = 3 end)
module M2 = F(struct let x = 5 end)
let () =
Format.printf "3 = %d, 5 = %d@." (new M1.c)#x (new M2.c)#x
let alloc_count = ref 0.
module Inherit (Parent : sig class c : object method x : int end end) = struct
let () = alloc_count := Gc.minor_words ()
class c = object inherit Parent.c end
let () = alloc_count := Gc.minor_words () -. !alloc_count
end
module N1 = Inherit(M1)
let () = Format.printf "N1: x = %d, alloc = %d@." (new N1.c)#x (truncate !alloc_count)
module N2 = Inherit(M2)
let () = Format.printf "N2: x = %d, alloc = %d@." (new N2.c)#x (truncate !alloc_count)The results are as follow: So nothing looks wrong and the optimisation still triggers.
I wish there was an explanation about the cache somewhere... I'm still not completely sure it works properly. |
|
@garrigue I've added a comment. I would appreciate if you could check that what I'm describing is in line with what you expect the code to do. |
garrigue
left a comment
There was a problem hiding this comment.
This looks ok now.
I'm still a bit concerned that we don't have that many tests for corner cases, but it really seems that the env_init stored in classes has never been used. The reason for my putting it there is a bit mysterious. It might be a that at some point the class itself was stored in the cache, but I could not find such code.
| and a dynamic part, the environment. The static part is cached | ||
| in a toplevel structure, so that only the first class creation | ||
| computes it and the subsequent classes can reuse it. Because of | ||
| that, the (static) [class_init] function takes the environment |
There was a problem hiding this comment.
takes both the class table to be filled and the environment as parameters
|
I'm working with @Ekdohibs on documenting the object compilation code, and we will likely produce additional tests to cover the features we document, but this is not our highest priority so it might be a while before we can actually submit a PR. |
* OCaml 5.3 Stdlib * conditionalize the changes in ocaml/ocaml#13193 * back to 5.3 * update to the latest upstream changes * add changelog entry
I eventually noticed (after spending some amount of time looking through the class and object code, for other reasons) that one of the four fields of class blocks was written to but never read from.
I looked around in all the suspicious places, and when I was convinced that there were indeed no accesses to this field directly or indirectly in all the places I knew where related to classes, I tentatively removed it (to find out if there were places manipulating classes that I was not aware of). The testsuite runs cleanly.
So I'm now convinced that the field isn't actually used, but I'm not sure whether it's a good idea to remove it or not. I'm submitting this PR to share my findings (and because I had written the code anyway), but I wouldn't be particularly disappointed if it was closed for one reason or another (if it's because the field is not actually unused, I want to hear about it though).
Cc @garrigue, who I assume is the person most likely to know about this.