Jump to page: 1 2
Thread overview
Is it possible to deinitialize the class without calling the gc?
Aug 03, 2018
12345swordy
Aug 03, 2018
Adam D. Ruppe
Aug 03, 2018
12345swordy
Aug 03, 2018
Adam D. Ruppe
Aug 03, 2018
12345swordy
Aug 03, 2018
Adam D. Ruppe
Aug 03, 2018
12345swordy
Aug 03, 2018
Adam D. Ruppe
Aug 04, 2018
12345swordy
Aug 04, 2018
12345swordy
Aug 04, 2018
Jonathan M Davis
Aug 04, 2018
Adam D. Ruppe
Aug 04, 2018
12345swordy
August 03, 2018
Call me curious, but I have never anyone done this before. I don't mean calling the .__dtor function as you can't call its parent .__dtor function. Is there RecusiveDestruct function that can be called that is attribute friendly?

-Alexander
August 03, 2018
On Friday, 3 August 2018 at 15:32:54 UTC, 12345swordy wrote:
> Is there RecusiveDestruct function that can be called that is attribute friendly?

No, the destructor definition in the language is not attribute friendly. Best you can do is `.destroy(obj)` and it can't see all the @nogc stuff (because the language doesn't actually support it here)
August 03, 2018
On Friday, 3 August 2018 at 15:41:13 UTC, Adam D. Ruppe wrote:
> On Friday, 3 August 2018 at 15:32:54 UTC, 12345swordy wrote:
>> Is there RecusiveDestruct function that can be called that is attribute friendly?
>
> No, the destructor definition in the language is not attribute friendly. Best you can do is `.destroy(obj)` and it can't see all the @nogc stuff (because the language doesn't actually support it here)

Your calling the gc if you call the destroy function for classes as it calls the rt_finalize function. Regardless you didn't answer the question that I posted in the title.

Alexander
August 03, 2018
On Friday, 3 August 2018 at 16:24:33 UTC, 12345swordy wrote:
> Your calling the gc if you call the destroy function for classes as it calls the rt_finalize function.

rt_finalize is not the GC. It just calls destructors in order for each base class.

> Regardless you didn't answer the question that I posted in the title.

Yes, I did. The .destroy function does that, but it ignores attributes.
August 03, 2018
On Friday, 3 August 2018 at 16:30:41 UTC, Adam D. Ruppe wrote:

> rt_finalize is not the GC.
Yes it is. That why is called finalize.
https://en.wikipedia.org/wiki/Finalizer

https://github.com/dlang/druntime/blob/633976f1b2619974e8b3b415e0052b38d1a8e2fb/src/gc/impl/manual/gc.d


-Alex
August 03, 2018
On Friday, 3 August 2018 at 17:50:10 UTC, 12345swordy wrote:
>> rt_finalize is not the GC.
> Yes it is. That why is called finalize.

OK, so you don't like it... because of its name?

It doesn't actually call any GC functions, it just loops through destructors and calls them all.
August 03, 2018
On Friday, 3 August 2018 at 18:52:13 UTC, Adam D. Ruppe wrote:

> OK, so you don't like it... because of its name?
Did you even bother reading the links that I posted? The term Finalize is commonly associated with OOP languages such as java and C#, while the term destructor is associated with C++. D has both of them. There has been some talks about splitting them.

> It doesn't actually call any GC functions, it just loops through destructors and calls them all.

Then you should know where the implementation of finalize is located at, or am I looking at the wrong code here?
August 03, 2018
On Friday, 3 August 2018 at 20:40:31 UTC, 12345swordy wrote:
> Did you even bother reading the links that I posted?

I did. Did you? The wikipedia page speaks at length to the ambiguity of the terms, including that the language construct can be called a destructor while the implementation methods can be called a finalizer, even if they do the same thing.


> Then you should know where the implementation of finalize is located at, or am I looking at the wrong code here?

It is in rt/lifetime.d.

The .destroy(class) function is defined on line 560 of object.d in druntime/src (assuming code as of v2.081.1 release). This calls rt_finalize, defined on line 1422 of rt/lifetime.d (and note that there is a separate function right under it for finalizeFromGC!).

This simply forwards to rt_finalize2, defined on line 1380 in the same file, which does the actual work. Observe how it simply calls the destructors, in order, of the base class instances, then deletes the monitor if it is present, and copies the initialize memory over to make that predictable, but then nulls out pointer to the rtti instance for that dead object, to ensure it is unusable.


The one you linked to is totally unrelated. It doesn't even define a function called destroy nor rt_finalize. It actually defines a function to finalize the (manual) GC object itself!

Its run finalizers method is supposed to detect what type of objects are in the passed memory block, and call rt_finalize (or one of its variants) for them. But, of course, since it is just a stub implementation of the GC interface, it doesn't actually do that.


rt_finalize is called BY the GC or the public destroy function, but it is NOT part of the GC. It also does not call into any GC functions itself (though user-defined hooks or class destructors might - but note if a class dtor does, it is liable to cause the program to terminate with InvalidMemoryOperatorError in certain circumstances).

It is also called by the language almost directly in the case of `scope` classes, via the `_d_callfinalizer` function (defined on line 1238 of rt/lifetime.d, where you can see it is a simple forward to rt_finalize). scope classes are allocated and destroyed just like structs - they live on the stack and their destructors are called deterministically when they go out of scope. Explicitly not GC'd... but still calling the same rt_finalize function.


BTW: Generally speaking, the calls to _d_xxxx functions are emitted by the compiler itself, then they forward to _rt_xxx functions, which are the internal runtime implementations, and those _rt_xxx functions are also accessible through other public interfaces, like the .destroy() function, or Runtime.xxx static struct methods, etc., to give them a prettier name. Those prettier names are the documented ways to access it, whereas the _rt_ ones are subject to change without notice by druntime devs and the _d_ ones are subject to change by dmd devs.



So, again:

> Is it possible to deinitialize the class without calling the gc?

Yes, use the .destroy function, or a scope class (or the scoped! template in std.typecons, which tried to replace the built-in scope thing due to memory safety concerns at one point).

> Is there RecusiveDestruct function that can be called that is attribute friendly?

No. Best you have is the .destroy function, which cannot work with the attributes because the D language definition does not make that possible. Child classes have independent destructors which do not need to adhere to the attributes of the parent class destructor, and moreover this cannot be detected at compile time when the attributes are processed - yet both must be called. Thus, at compile time, the destruction process must assume the widest possible features and the attributes do not apply.
August 04, 2018
On Friday, 3 August 2018 at 21:44:55 UTC, Adam D. Ruppe wrote:
>> Is it possible to deinitialize the class without calling the gc?
>
> Yes, use the .destroy function,
Which is converted to void type when passing the object to rt_finalize, which causes to lost all type information. How is this a better solution!?

> Child classes have independent destructors which do not need to adhere to the attributes of the parent class destructor,
Why is this an issue? Simply don't call them. There is no reason for a child class to adhere to the attribute of an empty destructor. If you want to be transparent of the possibility of them not being called, then create "destructor_hook".
> and moreover this cannot be detected at compile time when the attributes are processed
Are you telling me that D is incapable of determining the classes that is currently inheriting the parent class? That not even extern (D) can provide information to the compiler!? Do I need to add meta information section to my DIP?

I am not interested in a poor man solution here. This is a serious problem that needs addressing. I literally see the usage of __.dtor in the standard library! What's worst is that I seen sledge hammer approach to this by forcing the destroy function to be @nogc! I am not convinced that the upcoming protoObject is going to fix this issue given that old Object still exist.
August 04, 2018
On Saturday, 4 August 2018 at 02:21:48 UTC, 12345swordy wrote:

> Are you telling me that D is incapable of determining the classes that is currently inheriting the parent class? That not

*Create a list of child classes that is currently inheriting the parent class.

-Alexander
« First   ‹ Prev
1 2