Bug 728411 - Add new files for internal object structural details, as opposed to the external, ES5-like object interface. r=bhackett

--HG--
extra : rebase_source : 55d679f4576d8059deb265ae929b49b26e3c777e
This commit is contained in:
Jeff Walden 2012-02-09 18:54:28 -08:00
parent 141be33651
commit 66bba64a57
6 changed files with 189 additions and 120 deletions

View File

@ -154,6 +154,7 @@ CPPSRCS = \
Debugger.cpp \
GlobalObject.cpp \
MethodGuard.cpp \
ObjectImpl.cpp \
Stack.cpp \
String.cpp \
BytecodeCompiler.cpp \

View File

@ -148,6 +148,8 @@
* object allocation and the assignment.
*/
struct JSXML;
namespace js {
/*
@ -269,6 +271,10 @@ BarrieredSetPair(JSCompartment *comp,
v2.post();
}
struct Shape;
class BaseShape;
namespace types { struct TypeObject; }
typedef HeapPtr<JSObject> HeapPtrObject;
typedef HeapPtr<JSFunction> HeapPtrFunction;
typedef HeapPtr<JSString> HeapPtrString;

View File

@ -6242,10 +6242,6 @@ js_ClearNative(JSContext *cx, JSObject *obj)
return true;
}
static ObjectElements emptyObjectHeader(0, 0);
HeapValue *js::emptyObjectElements =
(HeapValue *) (uintptr_t(&emptyObjectHeader) + sizeof(ObjectElements));
JSBool
js_ReportGetterOnlyAssignment(JSContext *cx)
{

View File

@ -61,6 +61,8 @@
#include "jscell.h"
#include "gc/Barrier.h"
#include "vm/ObjectImpl.h"
#include "vm/String.h"
namespace js {
@ -391,133 +393,29 @@ class StringObject;
class RegExpObject;
class WithObject;
/*
* Header structure for object element arrays. This structure is immediately
* followed by an array of elements, with the elements member in an object
* pointing to the beginning of that array (the end of this structure).
* See below for usage of this structure.
*/
class ObjectElements
{
friend struct ::JSObject;
/* Number of allocated slots. */
uint32_t capacity;
/*
* Number of initialized elements. This is <= the capacity, and for arrays
* is <= the length. Memory for elements above the initialized length is
* uninitialized, but values between the initialized length and the proper
* length are conceptually holes.
*/
uint32_t initializedLength;
/* 'length' property of array objects, unused for other objects. */
uint32_t length;
/* :XXX: bug 586842 store state about sparse slots. */
uint32_t unused;
void staticAsserts() {
JS_STATIC_ASSERT(sizeof(ObjectElements) == VALUES_PER_HEADER * sizeof(Value));
}
public:
ObjectElements(uint32_t capacity, uint32_t length)
: capacity(capacity), initializedLength(0), length(length)
{}
HeapValue * elements() { return (HeapValue *)(uintptr_t(this) + sizeof(ObjectElements)); }
static ObjectElements * fromElements(HeapValue *elems) {
return (ObjectElements *)(uintptr_t(elems) - sizeof(ObjectElements));
}
static int offsetOfCapacity() {
return (int)offsetof(ObjectElements, capacity) - (int)sizeof(ObjectElements);
}
static int offsetOfInitializedLength() {
return (int)offsetof(ObjectElements, initializedLength) - (int)sizeof(ObjectElements);
}
static int offsetOfLength() {
return (int)offsetof(ObjectElements, length) - (int)sizeof(ObjectElements);
}
static const size_t VALUES_PER_HEADER = 2;
};
/* Shared singleton for objects with no elements. */
extern HeapValue *emptyObjectElements;
} /* namespace js */
/*
* JSObject struct. The JSFunction struct is an extension of this struct
* allocated from a larger GC size-class.
* The public interface for an object.
*
* The |shape_| member stores the shape of the object, which includes the
* object's class and the layout of all its properties.
* Implementation of the underlying structure occurs in ObjectImpl, from which
* this struct inherits. This inheritance is currently public, but it will
* eventually be made protected. For full details, see vm/ObjectImpl.{h,cpp}.
*
* The type member stores the type of the object, which contains its prototype
* object and the possible types of its properties.
*
* The rest of the object stores its named properties and indexed elements.
* These are stored separately from one another. Objects are followed by an
* variable-sized array of values for inline storage, which may be used by
* either properties of native objects (fixed slots) or by elements.
*
* Two native objects with the same shape are guaranteed to have the same
* number of fixed slots.
*
* Named property storage can be split between fixed slots and a dynamically
* allocated array (the slots member). For an object with N fixed slots, shapes
* with slots [0..N-1] are stored in the fixed slots, and the remainder are
* stored in the dynamic array. If all properties fit in the fixed slots, the
* 'slots' member is NULL.
*
* Elements are indexed via the 'elements' member. This member can point to
* either the shared emptyObjectElements singleton, into the inline value array
* (the address of the third value, to leave room for a ObjectElements header;
* in this case numFixedSlots() is zero) or to a dynamically allocated array.
*
* Only certain combinations of properties and elements storage are currently
* possible. This will be changing soon :XXX: bug 586842.
*
* - For objects other than arrays and typed arrays, the elements are empty.
*
* - For 'slow' arrays, both elements and properties are used, but the
* elements have zero capacity --- only the length member is used.
*
* - For dense arrays, elements are used and properties are not used.
*
* - For typed array buffers, elements are used and properties are not used.
* The data indexed by the elements do not represent Values, but primitive
* unboxed integers or floating point values.
* The JSFunction struct is an extension of this struct allocated from a larger
* GC size-class.
*/
struct JSObject : js::gc::Cell
struct JSObject : public js::ObjectImpl
{
private:
friend struct js::Shape;
friend struct js::GCMarker;
friend class js::NewObjectCache;
/*
* Shape of the object, encodes the layout of the object's properties and
* all other information about its structure. See jsscope.h.
*/
js::HeapPtrShape shape_;
#ifdef DEBUG
void checkShapeConsistency();
#endif
/*
* The object's type and prototype. For objects with the LAZY_TYPE flag
* set, this is the prototype's default 'new' type and can only be used
* to get that prototype.
*/
js::HeapPtrTypeObject type_;
/* Make the type object to use for LAZY_TYPE objects. */
void makeLazyType(JSContext *cx);
@ -575,12 +473,7 @@ struct JSObject : js::gc::Cell
/* Upper bound on the number of elements in an object. */
static const uint32_t NELEMENTS_LIMIT = JS_BIT(28);
private:
js::HeapValue *slots; /* Slots for object properties. */
js::HeapValue *elements; /* Slots for object elements. */
public:
inline bool isNative() const;
inline js::Class *getClass() const;

16
js/src/vm/ObjectImpl.cpp Normal file
View File

@ -0,0 +1,16 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sw=4 et tw=78:
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "ObjectImpl.h"
using namespace js;
static ObjectElements emptyElementsHeader(0, 0);
/* Objects with no elements share one empty set of elements. */
HeapValue *js::emptyObjectElements =
reinterpret_cast<HeapValue *>(uintptr_t(&emptyElementsHeader) + sizeof(ObjectElements));

157
js/src/vm/ObjectImpl.h Normal file
View File

@ -0,0 +1,157 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*-
* vim: set ts=8 sw=4 et tw=78:
*
* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#ifndef ObjectImpl_h___
#define ObjectImpl_h___
#include "mozilla/Assertions.h"
#include "mozilla/StdInt.h"
#include "gc/Barrier.h"
namespace js {
/*
* Header structure for object element arrays. This structure is immediately
* followed by an array of elements, with the elements member in an object
* pointing to the beginning of that array (the end of this structure).
* See below for usage of this structure.
*/
class ObjectElements
{
friend struct ::JSObject;
/* Number of allocated slots. */
uint32_t capacity;
/*
* Number of initialized elements. This is <= the capacity, and for arrays
* is <= the length. Memory for elements above the initialized length is
* uninitialized, but values between the initialized length and the proper
* length are conceptually holes.
*/
uint32_t initializedLength;
/* 'length' property of array objects, unused for other objects. */
uint32_t length;
/* :XXX: bug 586842 store state about sparse slots. */
uint32_t unused;
void staticAsserts() {
MOZ_STATIC_ASSERT(sizeof(ObjectElements) == VALUES_PER_HEADER * sizeof(Value),
"Elements size and values-per-Elements mismatch");
}
public:
ObjectElements(uint32_t capacity, uint32_t length)
: capacity(capacity), initializedLength(0), length(length)
{}
HeapValue * elements() { return (HeapValue *)(uintptr_t(this) + sizeof(ObjectElements)); }
static ObjectElements * fromElements(HeapValue *elems) {
return (ObjectElements *)(uintptr_t(elems) - sizeof(ObjectElements));
}
static int offsetOfCapacity() {
return (int)offsetof(ObjectElements, capacity) - (int)sizeof(ObjectElements);
}
static int offsetOfInitializedLength() {
return (int)offsetof(ObjectElements, initializedLength) - (int)sizeof(ObjectElements);
}
static int offsetOfLength() {
return (int)offsetof(ObjectElements, length) - (int)sizeof(ObjectElements);
}
static const size_t VALUES_PER_HEADER = 2;
};
/* Shared singleton for objects with no elements. */
extern HeapValue *emptyObjectElements;
struct Shape;
struct GCMarker;
class NewObjectCache;
/*
* ObjectImpl specifies the internal implementation of an object. (In contrast
* JSObject specifies an "external" interface, at the conceptual level of that
* exposed in ECMAScript.)
*
* The |shape_| member stores the shape of the object, which includes the
* object's class and the layout of all its properties.
*
* The type member stores the type of the object, which contains its prototype
* object and the possible types of its properties.
*
* The rest of the object stores its named properties and indexed elements.
* These are stored separately from one another. Objects are followed by an
* variable-sized array of values for inline storage, which may be used by
* either properties of native objects (fixed slots) or by elements.
*
* Two native objects with the same shape are guaranteed to have the same
* number of fixed slots.
*
* Named property storage can be split between fixed slots and a dynamically
* allocated array (the slots member). For an object with N fixed slots, shapes
* with slots [0..N-1] are stored in the fixed slots, and the remainder are
* stored in the dynamic array. If all properties fit in the fixed slots, the
* 'slots' member is NULL.
*
* Elements are indexed via the 'elements' member. This member can point to
* either the shared emptyObjectElements singleton, into the inline value array
* (the address of the third value, to leave room for a ObjectElements header;
* in this case numFixedSlots() is zero) or to a dynamically allocated array.
*
* Only certain combinations of properties and elements storage are currently
* possible. This will be changing soon :XXX: bug 586842.
*
* - For objects other than arrays and typed arrays, the elements are empty.
*
* - For 'slow' arrays, both elements and properties are used, but the
* elements have zero capacity --- only the length member is used.
*
* - For dense arrays, elements are used and properties are not used.
*
* - For typed array buffers, elements are used and properties are not used.
* The data indexed by the elements do not represent Values, but primitive
* unboxed integers or floating point values.
*
* The members of this class are currently protected; in the long run this will
* will change so that some members are private, and only certain methods that
* act upon them will be protected.
*/
class ObjectImpl : public gc::Cell
{
protected:
/*
* Shape of the object, encodes the layout of the object's properties and
* all other information about its structure. See jsscope.h.
*/
HeapPtrShape shape_;
/*
* The object's type and prototype. For objects with the LAZY_TYPE flag
* set, this is the prototype's default 'new' type and can only be used
* to get that prototype.
*/
HeapPtrTypeObject type_;
HeapValue *slots; /* Slots for object properties. */
HeapValue *elements; /* Slots for object elements. */
protected:
friend struct Shape;
friend struct GCMarker;
friend class NewObjectCache;
};
} /* namespace js */
#endif /* ObjectImpl_h__ */