32491566da
This reverts commit 0bc4d60fe0
.
Reason for revert: https://chromium-swarm.appspot.com/task?id=38007b6df51fef10&refresh=10
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Caught signal 6 [Aborted], was running:
8888 image scanline_kNonNative_premul interlaced3.png
unit test ArenaAllocReallyBigAlloc
unit test ClampRange
565 image scaled_codec_premul_0.200 interlaced3.png_0.200
unit test ClipStack
Likely culprit:
unit test ArenaAllocReallyBigAlloc
Stack trace:
/mnt/pd0/s/w/ir/out/Debug/dm(+0x2381c1) [0x567aa1c1]
linux-gate.so.1(__kernel_sigreturn+0) [0xf770cca0]
linux-gate.so.1(__kernel_vsyscall+0x9) [0xf770cc89]
/lib/i386-linux-gnu/libc.so.6(gsignal+0xb0) [0xf7027dc0]
/lib/i386-linux-gnu/libc.so.6(abort+0x157) [0xf7029287]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_ZN9__gnu_cxx27__verbose_terminate_handlerEv+0x16f) [0xf729d2ff]
/usr/lib/i386-linux-gnu/libstdc++.so.6(+0x71ea4) [0xf729aea4]
/usr/lib/i386-linux-gnu/libstdc++.so.6(+0x71f1d) [0xf729af1d]
/usr/lib/i386-linux-gnu/libstdc++.so.6(__cxa_rethrow+0) [0xf729b1d0]
/usr/lib/i386-linux-gnu/libstdc++.so.6(+0x727ff) [0xf729b7ff]
/usr/lib/i386-linux-gnu/libstdc++.so.6(_Znaj+0x18) [0xf729b898]
/mnt/pd0/s/w/ir/out/Debug/dm(_ZN12SkArenaAlloc11ensureSpaceEjj+0xa0) [0x56f113a6]
/mnt/pd0/s/w/ir/out/Debug/dm(+0x3c2462) [0x56934462]
/mnt/pd0/s/w/ir/out/Debug/dm(+0x239acb) [0x567abacb]
/mnt/pd0/s/w/ir/out/Debug/dm(+0x239bdc) [0x567abbdc]
/mnt/pd0/s/w/ir/out/Debug/dm(+0xa6417b) [0x56fd617b]
/mnt/pd0/s/w/ir/out/Debug/dm(_ZNKSt8functionIFvvEEclEv+0x20) [0x56f10504]
/mnt/pd0/s/w/ir/out/Debug/dm(_ZN12SkThreadPool4LoopEPv+0x298) [0x56f10bdb]
/mnt/pd0/s/w/ir/out/Debug/dm(+0xb39700) [0x570ab700]
/lib/i386-linux-gnu/libpthread.so.0(+0x627a) [0xf76df27a]
/lib/i386-linux-gnu/libc.so.6(clone+0x66) [0xf70e3b56]
Aborted
Command exited with code 134
Original change's description:
> Fix bogus math in object allocation.
>
> When a size_t is convert from a very large number to ptrdiff_t, it
> becomes negative causing the existing block to be used instead of
> allocating a new block.
>
> BUG=chromium:744109
>
> Change-Id: I0bf98e3fb924851c162f6eca43d29a3f40dc9eaa
> Reviewed-on: https://skia-review.googlesource.com/34541
> Reviewed-by: Ben Wagner <bungeman@google.com>
> Commit-Queue: Herb Derby <herb@google.com>
TBR=bungeman@google.com,herb@google.com
Change-Id: I8ce2b45d13178395247dabd7af6853354399721c
No-Presubmit: true
No-Tree-Checks: true
No-Try: true
Bug: chromium:744109
Reviewed-on: https://skia-review.googlesource.com/35000
Reviewed-by: Florin Malita <fmalita@chromium.org>
Commit-Queue: Florin Malita <fmalita@chromium.org>
184 lines
4.9 KiB
C++
184 lines
4.9 KiB
C++
/*
|
|
* Copyright 2016 Google Inc.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license that can be
|
|
* found in the LICENSE file.
|
|
*/
|
|
|
|
#include "Test.h"
|
|
#include "SkArenaAlloc.h"
|
|
#include "SkRefCnt.h"
|
|
|
|
namespace {
|
|
|
|
static int created, destroyed;
|
|
|
|
struct Foo {
|
|
Foo() : x(-2), y(-3.0f) { created++; }
|
|
Foo(int X, float Y) : x(X), y(Y) { created++; }
|
|
~Foo() { destroyed++; }
|
|
|
|
int x;
|
|
float y;
|
|
};
|
|
|
|
struct Big {
|
|
Big() {}
|
|
uint32_t array[128];
|
|
};
|
|
|
|
struct Node {
|
|
Node(Node* n) : next(n) { created++; }
|
|
~Node() {
|
|
destroyed++;
|
|
if (next) {
|
|
next->~Node();
|
|
}
|
|
}
|
|
Node *next;
|
|
};
|
|
|
|
struct Start {
|
|
~Start() {
|
|
if (start) {
|
|
start->~Node();
|
|
}
|
|
}
|
|
Node* start;
|
|
};
|
|
|
|
struct FooRefCnt : public SkRefCnt {
|
|
FooRefCnt() : x(-2), y(-3.0f) { created++; }
|
|
FooRefCnt(int X, float Y) : x(X), y(Y) { created++; }
|
|
~FooRefCnt() { destroyed++; }
|
|
|
|
int x;
|
|
float y;
|
|
};
|
|
|
|
}
|
|
|
|
struct WithDtor {
|
|
~WithDtor() { }
|
|
};
|
|
|
|
DEF_TEST(ArenaAlloc, r) {
|
|
|
|
{
|
|
created = 0;
|
|
destroyed = 0;
|
|
|
|
SkArenaAlloc arena{0};
|
|
REPORTER_ASSERT(r, *arena.make<int>(3) == 3);
|
|
Foo* foo = arena.make<Foo>(3, 4.0f);
|
|
REPORTER_ASSERT(r, foo->x == 3);
|
|
REPORTER_ASSERT(r, foo->y == 4.0f);
|
|
REPORTER_ASSERT(r, created == 1);
|
|
REPORTER_ASSERT(r, destroyed == 0);
|
|
arena.makeArrayDefault<int>(10);
|
|
int* zeroed = arena.makeArray<int>(10);
|
|
for (int i = 0; i < 10; i++) {
|
|
REPORTER_ASSERT(r, zeroed[i] == 0);
|
|
}
|
|
Foo* fooArray = arena.makeArrayDefault<Foo>(10);
|
|
REPORTER_ASSERT(r, fooArray[3].x == -2);
|
|
REPORTER_ASSERT(r, fooArray[4].y == -3.0f);
|
|
REPORTER_ASSERT(r, created == 11);
|
|
REPORTER_ASSERT(r, destroyed == 0);
|
|
arena.make<typename std::aligned_storage<10,8>::type>();
|
|
}
|
|
REPORTER_ASSERT(r, created == 11);
|
|
REPORTER_ASSERT(r, destroyed == 11);
|
|
|
|
{
|
|
created = 0;
|
|
destroyed = 0;
|
|
SkSTArenaAlloc<64> arena;
|
|
|
|
REPORTER_ASSERT(r, *arena.make<int>(3) == 3);
|
|
Foo* foo = arena.make<Foo>(3, 4.0f);
|
|
REPORTER_ASSERT(r, foo->x == 3);
|
|
REPORTER_ASSERT(r, foo->y == 4.0f);
|
|
REPORTER_ASSERT(r, created == 1);
|
|
REPORTER_ASSERT(r, destroyed == 0);
|
|
arena.makeArrayDefault<int>(10);
|
|
int* zeroed = arena.makeArray<int>(10);
|
|
for (int i = 0; i < 10; i++) {
|
|
REPORTER_ASSERT(r, zeroed[i] == 0);
|
|
}
|
|
Foo* fooArray = arena.makeArrayDefault<Foo>(10);
|
|
REPORTER_ASSERT(r, fooArray[3].x == -2);
|
|
REPORTER_ASSERT(r, fooArray[4].y == -3.0f);
|
|
REPORTER_ASSERT(r, created == 11);
|
|
REPORTER_ASSERT(r, destroyed == 0);
|
|
arena.make<typename std::aligned_storage<10,8>::type>();
|
|
}
|
|
REPORTER_ASSERT(r, created == 11);
|
|
REPORTER_ASSERT(r, destroyed == 11);
|
|
|
|
{
|
|
created = 0;
|
|
destroyed = 0;
|
|
std::unique_ptr<char[]> block{new char[1024]};
|
|
SkArenaAlloc arena{block.get(), 1024, 0};
|
|
|
|
REPORTER_ASSERT(r, *arena.make<int>(3) == 3);
|
|
Foo* foo = arena.make<Foo>(3, 4.0f);
|
|
REPORTER_ASSERT(r, foo->x == 3);
|
|
REPORTER_ASSERT(r, foo->y == 4.0f);
|
|
REPORTER_ASSERT(r, created == 1);
|
|
REPORTER_ASSERT(r, destroyed == 0);
|
|
arena.makeArrayDefault<int>(10);
|
|
int* zeroed = arena.makeArray<int>(10);
|
|
for (int i = 0; i < 10; i++) {
|
|
REPORTER_ASSERT(r, zeroed[i] == 0);
|
|
}
|
|
Foo* fooArray = arena.makeArrayDefault<Foo>(10);
|
|
REPORTER_ASSERT(r, fooArray[3].x == -2);
|
|
REPORTER_ASSERT(r, fooArray[4].y == -3.0f);
|
|
REPORTER_ASSERT(r, created == 11);
|
|
REPORTER_ASSERT(r, destroyed == 0);
|
|
arena.make<typename std::aligned_storage<10,8>::type>();
|
|
}
|
|
REPORTER_ASSERT(r, created == 11);
|
|
REPORTER_ASSERT(r, destroyed == 11);
|
|
|
|
{
|
|
SkSTArenaAlloc<64> arena;
|
|
arena.makeArrayDefault<char>(256);
|
|
arena.reset();
|
|
arena.reset();
|
|
}
|
|
|
|
{
|
|
created = 0;
|
|
destroyed = 0;
|
|
SkSTArenaAlloc<64> arena;
|
|
|
|
Start start;
|
|
Node* current = nullptr;
|
|
for (int i = 0; i < 128; i++) {
|
|
uint64_t* temp = arena.makeArrayDefault<uint64_t>(sizeof(Node) / sizeof(Node*));
|
|
current = new (temp)Node(current);
|
|
}
|
|
start.start = current;
|
|
}
|
|
|
|
REPORTER_ASSERT(r, created == 128);
|
|
REPORTER_ASSERT(r, destroyed == 128);
|
|
|
|
{
|
|
created = 0;
|
|
destroyed = 0;
|
|
SkSTArenaAlloc<64> arena;
|
|
|
|
sk_sp<FooRefCnt> f = arena.makeSkSp<FooRefCnt>(4, 5.0f);
|
|
REPORTER_ASSERT(r, f->x == 4);
|
|
REPORTER_ASSERT(r, f->y == 5.0f);
|
|
REPORTER_ASSERT(r, created == 1);
|
|
REPORTER_ASSERT(r, destroyed == 0);
|
|
}
|
|
REPORTER_ASSERT(r, created == 1);
|
|
REPORTER_ASSERT(r, destroyed == 1);
|
|
}
|