bf67f24098
The purpose of this change is twofold: 1. Source in the bin directory can now use the same assertions as source in the vm directory. The ASSERT macro used by the code in runtime/bin was just defined to use assert from the standard C library. 2. Moving other implementation parts from runtime/vm to runtime/platform (e.g. classes Monitor and Mutex) for sharing between runtime/bin and runtime/vm will be easier as these implementations rely on these assertion macros. Created two gypi files for the platform directory. One for the headers and one for the source. The source one is only included when building the VM library and will be present in libdart.a when the dart executable is linked. All the code for asserts is still in the dart namespace. Also re-arranged the order of includes to be alphabetically in the files touched. R=ager@google.com, iposva@google.com BUG= TEST= Review URL: http://codereview.chromium.org//9189003 git-svn-id: https://dart.googlecode.com/svn/branches/bleeding_edge/dart@3335 260f80e4-7a28-3924-810f-c04153c831b5
108 lines
3.2 KiB
C++
108 lines
3.2 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/raw_object.h"
|
|
|
|
namespace dart {
|
|
|
|
// FreeListElement describes a freelist element that has the same size
|
|
// as the smallest raw object. It uses the class_ field to point to a fake map
|
|
// to enable basic traversing of the heap and to identify the type of freelist
|
|
// element. It reuses the second word of the raw object to keep a next_
|
|
// pointer to chain elements of the list together. For objects larger than the
|
|
// minimal object size, the size of the element is embedded in the element at
|
|
// the address following the next_ field.
|
|
class FreeListElement {
|
|
public:
|
|
FreeListElement* next() const {
|
|
// Clear the FreeBit.
|
|
ASSERT((next_ & 1) == 1);
|
|
return reinterpret_cast<FreeListElement*>(next_ ^ 1);
|
|
}
|
|
void set_next(FreeListElement* next) {
|
|
// Set the FreeBit.
|
|
uword addr = reinterpret_cast<uword>(next);
|
|
ASSERT((addr & 1) == 0);
|
|
next_ = addr | 1;
|
|
}
|
|
|
|
intptr_t Size() const {
|
|
if (class_ == minimal_element_class_) {
|
|
return kObjectAlignment;
|
|
}
|
|
ASSERT(class_ == element_class_);
|
|
return *SizeAddress();
|
|
}
|
|
|
|
static FreeListElement* AsElement(uword addr, intptr_t size);
|
|
|
|
static bool IsSpecialClass(RawObject* raw_obj) {
|
|
return (raw_obj == minimal_element_class_) || (raw_obj == element_class_);
|
|
}
|
|
|
|
static void InitOnce();
|
|
|
|
private:
|
|
// This layout mirrors the layout of RawObject.
|
|
RawClass* class_;
|
|
uword next_;
|
|
|
|
// Returns the address of the embedded size.
|
|
intptr_t* SizeAddress() const {
|
|
ASSERT(class_ == element_class_);
|
|
uword addr = reinterpret_cast<uword>(&next_) + kWordSize;
|
|
return reinterpret_cast<intptr_t*>(addr);
|
|
}
|
|
|
|
// The two fake classe being used by the FreeList to identify free objects in
|
|
// the heap. These can be static and shared between isolates since they
|
|
// contain no per-isolate information. Actually, they need to be static so
|
|
// that they can be used from free list elements efficiently.
|
|
// The minimal_element_class_ is used by minimally sized free list elements
|
|
// which cannot hold the size within the element.
|
|
// element_class_ is used for free lists elements containing a size.
|
|
static RawClass* minimal_element_class_;
|
|
static RawClass* element_class_;
|
|
|
|
// 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);
|
|
void Free(uword addr, intptr_t size);
|
|
|
|
void Reset();
|
|
|
|
private:
|
|
static const int kNumLists = 128;
|
|
|
|
static intptr_t IndexForSize(intptr_t size);
|
|
|
|
void EnqueueElement(FreeListElement* element, intptr_t index);
|
|
FreeListElement* DequeueElement(intptr_t index);
|
|
|
|
void SplitElementAfterAndEnqueue(FreeListElement* element, intptr_t size);
|
|
|
|
FreeListElement* free_lists_[kNumLists + 1];
|
|
|
|
DISALLOW_COPY_AND_ASSIGN(FreeList);
|
|
};
|
|
|
|
} // namespace dart
|
|
|
|
#endif // VM_FREELIST_H_
|