Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

"Infallible alloc" stage 1 landed (and stuck)

16 views
Skip to first unread message

Chris Jones

unread,
Mar 5, 2010, 5:27:08 AM3/5/10
to
First a note on terminology --- "infallible alloc" means an allocator
never returning NULL, i.e. never failing. A "fallible alloc" might
return NULL.

The only "visible" change made by stage 1 allocators is that |new Foo()|
is now infallible, and its result does *not* need to be NULL checked.
The libc allocators, malloc() et al., have not changed: they're still
fallible.

Stage 1 adds explicitly fallible and infallible libc allocators. The
fallible versions are moz_malloc() et al. Currently, malloc() et al.
are #define'd to the explicitly fallible variants. In stage 2, we will
determine which sites are allocating large chunks of memory and convert
them to be explicitly fallible, moz_malloc() et al. After those are
rewritten, we'll #define malloc() to its infallible variant, moz_xmalloc().

In new code: if you're potentially malloc()ing a large chunk of memory,
use moz_malloc() directly and NULL check. If you're not sure, use
malloc() and NULL check.

Stage 1 also adds explicitly fallible and infallible |::operator new|s.
The default is infallible, |new Foo()|. The fallible variant can be
invoked with |new (fallible_t()) Foo()|.

In new code: if you're not sure which operator new to use, use |new
Foo()| and don't NULL check.

Summary:

// infallible forever
f = new Foo();
fa = new Foo[];

// infallible forever
n = ::operator new(...);
n = ::operator new[](...);

namespace mozilla {
// fallible forever
f = new (fallible_t()) Foo();
fa = new (fallible_t()) Foo[];

// fallible forever
f = ::operator new(fallible_t(), ...);
fa = ::operator new[](fallible_t(), ...);
}

// fallible for now, until stage 2
p = malloc();
...

// fallible forever
p = moz_malloc();
...

// infallible forever
p = moz_xmalloc();
...

// fallible for now, until stage 2
p = NS_Alloc();

Cheers,
Chris

Neil

unread,
Mar 5, 2010, 5:49:43 AM3/5/10
to
Chris Jones wrote:

> // fallible forever
> p = moz_malloc();
> ...
>
> // infallible forever
> p = moz_xmalloc();
> ...

Which underlying allocator do these calls use, i.e. can they be made to
use jemalloc on those build configurations that don't currently support it?

--
Warning: May contain traces of nuts.

Mark Banner

unread,
Mar 5, 2010, 6:56:58 AM3/5/10
to
On 05/03/2010 10:27, Chris Jones wrote:
> First a note on terminology --- "infallible alloc" means an allocator
> never returning NULL, i.e. never failing. A "fallible alloc" might
> return NULL.

Is there going to be a dev doc explaining all of this and the
recommended ways going forward? I think it will be needed.

> Stage 1 adds explicitly fallible and infallible libc allocators. The
> fallible versions are moz_malloc() et al. Currently, malloc() et al. are
> #define'd to the explicitly fallible variants. In stage 2, we will
> determine which sites are allocating large chunks of memory and convert
> them to be explicitly fallible, moz_malloc() et al. After those are
> rewritten, we'll #define malloc() to its infallible variant, moz_xmalloc().

Stage 2 sounds like a semi-manual processed based on a snapshot of the
existing code. How would other apps do this analysis, and how does
assessment take place after stage 2 is completed?

Standard8

Boris Zbarsky

unread,
Mar 5, 2010, 10:15:00 AM3/5/10
to
On 3/5/10 5:27 AM, Chris Jones wrote:
> Stage 1 adds explicitly fallible and infallible libc allocators. The
> fallible versions are moz_malloc() et al. Currently, malloc() et al. are
> #define'd to the explicitly fallible variants. In stage 2, we will
> determine which sites are allocating large chunks of memory and convert
> them to be explicitly fallible, moz_malloc() et al.

We also need to do this for new[], right?

-Boris

Shawn Wilsher

unread,
Mar 5, 2010, 11:51:29 AM3/5/10
to dev-pl...@lists.mozilla.org
On 3/5/2010 3:56 AM, Mark Banner wrote:
> Stage 2 sounds like a semi-manual processed based on a snapshot of the
> existing code. How would other apps do this analysis, and how does
> assessment take place after stage 2 is completed?
I would hope that reviews start paying attention to this. That's how we
would manage this post stage 2, correct?

Cheers,

Shawn

Sheppy

unread,
Mar 5, 2010, 1:43:53 PM3/5/10
to
I've started documentation on this here:

https://developer.mozilla.org/en/Infallible_memory_allocation

It will be tied into a few other articles here and there soon.

I have a question: how are these infallible? Do they abort the app if
memory simply can't be allocated?

Sheppy

Sheppy

unread,
Mar 5, 2010, 1:54:07 PM3/5/10
to
If someone would like to review the infallible allocators article at
https://developer.mozilla.org/en/Infallible_memory_allocation to
confirm my interpretations are correct, that'd be helpful.

Thanks,
Sheppy

Chris Jones

unread,
Mar 5, 2010, 2:18:21 PM3/5/10
to
Neil wrote:
> Chris Jones wrote:
>
>> // fallible forever
>> p = moz_malloc();
>> ...
>>
>> // infallible forever
>> p = moz_xmalloc();
>> ...
>
> Which underlying allocator do these calls use, i.e. can they be made to
> use jemalloc on those build configurations that don't currently support it?
>

Yes and no. We could, but then we'd end up with at least two heaps and
would need to be extremely careful about memory crossing
platform-library boundaries. AFAIK there aren't immediate plans to look
into this.

Cheers,
Chris

Chris Jones

unread,
Mar 5, 2010, 2:22:47 PM3/5/10
to
Mark Banner wrote:
> On 05/03/2010 10:27, Chris Jones wrote:
>> First a note on terminology --- "infallible alloc" means an allocator
>> never returning NULL, i.e. never failing. A "fallible alloc" might
>> return NULL.
>
> Is there going to be a dev doc explaining all of this and the
> recommended ways going forward? I think it will be needed.
>

Probably ...

>> Stage 1 adds explicitly fallible and infallible libc allocators. The
>> fallible versions are moz_malloc() et al. Currently, malloc() et al. are
>> #define'd to the explicitly fallible variants. In stage 2, we will
>> determine which sites are allocating large chunks of memory and convert
>> them to be explicitly fallible, moz_malloc() et al. After those are
>> rewritten, we'll #define malloc() to its infallible variant,
>> moz_xmalloc().
>
> Stage 2 sounds like a semi-manual processed based on a snapshot of the
> existing code. How would other apps do this analysis, and how does
> assessment take place after stage 2 is completed?
>

We plan on doing a mostly-automatic dynamic analysis with something like
dtrace tool to see which callsites allocate big chunks. Depending on
the number, we could either rewrite manually or cook up an automatic
rewrite tool. None of that is app-specific; the analysis phase just
requires a good testsuite or a large barrel of test monkeys willing to
run the analysis scripts while browsing.

Cheers,
Chris

Chris Jones

unread,
Mar 5, 2010, 2:23:47 PM3/5/10
to

Yes, and we can keep an eye on crash stats and periodically re-run the
"big allocation sites" analysis.

Cheers,
Chris

Chris Jones

unread,
Mar 5, 2010, 2:25:35 PM3/5/10
to

Yes. The plan was to analyze malloc() et al., which new and new[] call
into.

Cheers,
Chris

Chris Jones

unread,
Mar 5, 2010, 2:28:48 PM3/5/10
to

For stage 1, yes. Stage 2 will attempt to recover from critically low
memory by various means, but will still abort if that fails.

Cheers,
Chris

Chris Jones

unread,
Mar 5, 2010, 3:22:57 PM3/5/10
to

Looks good to me. I'll be sure to update as things change.

Cheers,
Chris

Sheppy

unread,
Mar 5, 2010, 3:39:05 PM3/5/10
to

OK, I've added some additional info to that effect. Thanks!

Sheppy

Neil

unread,
Mar 6, 2010, 4:39:55 PM3/6/10
to
Chris Jones wrote:

> Neil wrote:
>
>> Chris Jones wrote:
>>
>>> // fallible forever
>>> p = moz_malloc();
>>> ...
>>>
>>> // infallible forever
>>> p = moz_xmalloc();
>>> ...
>>
>> Which underlying allocator do these calls use, i.e. can they be made
>> to use jemalloc on those build configurations that don't currently
>> support it?
>
> Yes and no. We could, but then we'd end up with at least two heaps
> and would need to be extremely careful about memory crossing
> platform-library boundaries.

Well, I have a build with multiple heaps (new, new[], malloc, PR_Malloc,
NS_Alloc, PL_strdup) and it mostly works (there are a couple of
allocator mismatches still in the tree).

0 new messages