Files
sdk/runtime/vm/freelist.h
T
koda@google.com 95bdd07cfb Never mark free list elements.
Avoid confusion between heap premarking and verification by introducing the
invariant that FreeListElement is never marked.

Also fix incorrect statement about instruction objects being allocated premarked.

R=iposva@google.com

Review URL: https://codereview.chromium.org//1092473002

git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@45185 260f80e4-7a28-3924-810f-c04153c831b5
2015-04-15 22:18:07 +00:00

139 lines
3.9 KiB
C++

// Copyright (c) 2012, the Dart project authors. Please see the AUTHORS file
// for details. All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
#ifndef VM_FREELIST_H_
#define VM_FREELIST_H_
#include "platform/assert.h"
#include "vm/allocation.h"
#include "vm/bit_set.h"
#include "vm/raw_object.h"
#include "vm/os_thread.h"
namespace dart {
// FreeListElement describes a freelist element. Smallest FreeListElement is
// two words in size. Second word of the raw object is used to keep a next_
// pointer to chain elements of the list together. For objects larger than the
// object size encodable in tags field, the size of the element is embedded in
// the element at the address following the next_ field. All words written by
// the freelist are guaranteed to look like smis, as required by
// TryAllocateSmiInitializedLocked.
// A FreeListElement never has its header mark bit set.
class FreeListElement {
public:
FreeListElement* next() const {
return next_;
}
uword next_address() const {
return reinterpret_cast<uword>(&next_);
}
void set_next(FreeListElement* next) {
next_ = next;
}
intptr_t Size() {
intptr_t size = RawObject::SizeTag::decode(tags_);
if (size != 0) return size;
return *SizeAddress();
}
static FreeListElement* AsElement(uword addr, intptr_t size);
static void InitOnce();
static intptr_t HeaderSizeFor(intptr_t size);
// Used to allocate class for free list elements in Object::InitOnce.
class FakeInstance {
public:
FakeInstance() { }
static cpp_vtable vtable() { return 0; }
static intptr_t InstanceSize() { return 0; }
static intptr_t NextFieldOffset() { return -kWordSize; }
static const ClassId kClassId = kFreeListElement;
static bool IsInstance() { return true; }
private:
DISALLOW_ALLOCATION();
DISALLOW_COPY_AND_ASSIGN(FakeInstance);
};
private:
// This layout mirrors the layout of RawObject.
uword tags_;
FreeListElement* next_;
// Returns the address of the embedded size.
intptr_t* SizeAddress() const {
uword addr = reinterpret_cast<uword>(&next_) + kWordSize;
return reinterpret_cast<intptr_t*>(addr);
}
// FreeListElements cannot be allocated. Instead references to them are
// created using the AsElement factory method.
DISALLOW_ALLOCATION();
DISALLOW_IMPLICIT_CONSTRUCTORS(FreeListElement);
};
class FreeList {
public:
FreeList();
~FreeList();
uword TryAllocate(intptr_t size, bool is_protected);
void Free(uword addr, intptr_t size);
void Reset();
void Print() const;
Mutex* mutex() { return mutex_; }
uword TryAllocateLocked(intptr_t size, bool is_protected);
void FreeLocked(uword addr, intptr_t size);
// Returns a large element, at least 'minimum_size', or NULL if none exists.
FreeListElement* TryAllocateLarge(intptr_t minimum_size);
FreeListElement* TryAllocateLargeLocked(intptr_t minimum_size);
// Allocates locked and unprotected memory, but only from small elements
// (i.e., fixed size lists).
uword TryAllocateSmallLocked(intptr_t size);
private:
static const int kNumLists = 128;
static intptr_t IndexForSize(intptr_t size);
intptr_t LengthLocked(int index) const;
void EnqueueElement(FreeListElement* element, intptr_t index);
FreeListElement* DequeueElement(intptr_t index);
void SplitElementAfterAndEnqueue(FreeListElement* element,
intptr_t size,
bool is_protected);
void PrintSmall() const;
void PrintLarge() const;
// Lock protecting the free list data structures.
Mutex* mutex_;
BitSet<kNumLists> free_map_;
FreeListElement* free_lists_[kNumLists + 1];
// The largest available small size in bytes, or negative if there is none.
intptr_t last_free_small_size_;
DISALLOW_COPY_AND_ASSIGN(FreeList);
};
} // namespace dart
#endif // VM_FREELIST_H_