blob: 139b8622bb851d0c0f8f60263656ab48e887c53e [file] [log] [blame]
fpizlo@apple.coma4b4cbe2013-01-12 04:47:03 +00001/*
oliver@apple.comf322a222013-07-25 03:59:49 +00002 * Copyright (C) 2012, 2013 Apple Inc. All rights reserved.
fpizlo@apple.coma4b4cbe2013-01-12 04:47:03 +00003 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions
6 * are met:
7 * 1. Redistributions of source code must retain the above copyright
8 * notice, this list of conditions and the following disclaimer.
9 * 2. Redistributions in binary form must reproduce the above copyright
10 * notice, this list of conditions and the following disclaimer in the
11 * documentation and/or other materials provided with the distribution.
12 *
13 * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
14 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
15 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
17 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
18 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
19 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
20 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
21 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
23 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
mhahnenberg@apple.comdc3d1482013-02-01 23:10:49 +000026#ifndef JSCellInlines_h
27#define JSCellInlines_h
28
fpizlo@apple.coma4b4cbe2013-01-12 04:47:03 +000029#include "CallFrame.h"
mhahnenberg@apple.comefd0d512013-10-16 23:47:45 +000030#include "DeferGC.h"
mhahnenberg@apple.comdc3d1482013-02-01 23:10:49 +000031#include "Handle.h"
fpizlo@apple.coma4b4cbe2013-01-12 04:47:03 +000032#include "JSCell.h"
mhahnenberg@apple.comdc3d1482013-02-01 23:10:49 +000033#include "JSObject.h"
34#include "JSString.h"
35#include "Structure.h"
oliver@apple.comf322a222013-07-25 03:59:49 +000036#include <wtf/CompilationThread.h>
fpizlo@apple.coma4b4cbe2013-01-12 04:47:03 +000037
38namespace JSC {
39
40inline JSCell::JSCell(CreatingEarlyCellTag)
41{
oliver@apple.comf322a222013-07-25 03:59:49 +000042 ASSERT(!isCompilationThread());
fpizlo@apple.coma4b4cbe2013-01-12 04:47:03 +000043}
44
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +000045inline JSCell::JSCell(VM& vm, Structure* structure)
46 : m_structure(vm, this, structure)
fpizlo@apple.coma4b4cbe2013-01-12 04:47:03 +000047{
oliver@apple.comf322a222013-07-25 03:59:49 +000048 ASSERT(!isCompilationThread());
fpizlo@apple.coma4b4cbe2013-01-12 04:47:03 +000049}
50
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +000051inline void JSCell::finishCreation(VM& vm)
fpizlo@apple.coma4b4cbe2013-01-12 04:47:03 +000052{
53#if ENABLE(GC_VALIDATION)
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +000054 ASSERT(vm.isInitializingObject());
55 vm.setInitializingObjectClass(0);
fpizlo@apple.coma4b4cbe2013-01-12 04:47:03 +000056#else
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +000057 UNUSED_PARAM(vm);
fpizlo@apple.coma4b4cbe2013-01-12 04:47:03 +000058#endif
59 ASSERT(m_structure);
60}
61
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +000062inline void JSCell::finishCreation(VM& vm, Structure* structure, CreatingEarlyCellTag)
fpizlo@apple.coma4b4cbe2013-01-12 04:47:03 +000063{
64#if ENABLE(GC_VALIDATION)
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +000065 ASSERT(vm.isInitializingObject());
66 vm.setInitializingObjectClass(0);
fpizlo@apple.coma4b4cbe2013-01-12 04:47:03 +000067 if (structure)
68#endif
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +000069 m_structure.setEarlyValue(vm, this, structure);
fpizlo@apple.coma4b4cbe2013-01-12 04:47:03 +000070 // Very first set of allocations won't have a real structure.
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +000071 ASSERT(m_structure || !vm.structureStructure);
fpizlo@apple.coma4b4cbe2013-01-12 04:47:03 +000072}
73
74inline Structure* JSCell::structure() const
75{
76 return m_structure.get();
77}
78
79inline void JSCell::visitChildren(JSCell* cell, SlotVisitor& visitor)
80{
81 MARK_LOG_PARENT(visitor, cell);
82
83 visitor.append(&cell->m_structure);
84}
85
86template<typename T>
87void* allocateCell(Heap& heap, size_t size)
88{
mhahnenberg@apple.comefd0d512013-10-16 23:47:45 +000089 ASSERT(!DisallowGC::isGCDisallowedOnCurrentThread());
fpizlo@apple.coma4b4cbe2013-01-12 04:47:03 +000090 ASSERT(size >= sizeof(T));
91#if ENABLE(GC_VALIDATION)
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +000092 ASSERT(!heap.vm()->isInitializingObject());
fpizlo@apple.com10ae2d02013-08-14 02:41:47 +000093 heap.vm()->setInitializingObjectClass(T::info());
fpizlo@apple.coma4b4cbe2013-01-12 04:47:03 +000094#endif
95 JSCell* result = 0;
96 if (T::needsDestruction && T::hasImmortalStructure)
97 result = static_cast<JSCell*>(heap.allocateWithImmortalStructureDestructor(size));
ggaren@apple.comc862eac2013-01-29 05:48:01 +000098 else if (T::needsDestruction)
fpizlo@apple.coma4b4cbe2013-01-12 04:47:03 +000099 result = static_cast<JSCell*>(heap.allocateWithNormalDestructor(size));
100 else
101 result = static_cast<JSCell*>(heap.allocateWithoutDestructor(size));
102 result->clearStructure();
103 return result;
104}
105
106template<typename T>
107void* allocateCell(Heap& heap)
108{
109 return allocateCell<T>(heap, sizeof(T));
110}
111
112inline bool isZapped(const JSCell* cell)
113{
114 return cell->isZapped();
115}
116
117inline bool JSCell::isObject() const
118{
119 return m_structure->isObject();
120}
121
122inline bool JSCell::isString() const
123{
124 return m_structure->typeInfo().type() == StringType;
125}
126
127inline bool JSCell::isGetterSetter() const
128{
129 return m_structure->typeInfo().type() == GetterSetterType;
130}
131
132inline bool JSCell::isProxy() const
133{
134 return structure()->typeInfo().type() == ProxyType;
135}
136
137inline bool JSCell::isAPIValueWrapper() const
138{
139 return m_structure->typeInfo().type() == APIValueWrapperType;
140}
141
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000142inline void JSCell::setStructure(VM& vm, Structure* structure)
fpizlo@apple.coma4b4cbe2013-01-12 04:47:03 +0000143{
144 ASSERT(structure->typeInfo().overridesVisitChildren() == this->structure()->typeInfo().overridesVisitChildren());
145 ASSERT(structure->classInfo() == m_structure->classInfo());
146 ASSERT(!m_structure
147 || m_structure->transitionWatchpointSetHasBeenInvalidated()
148 || m_structure.get() == structure);
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000149 m_structure.set(vm, this, structure);
fpizlo@apple.coma4b4cbe2013-01-12 04:47:03 +0000150}
151
oliver@apple.comb6b94a92013-01-30 01:31:37 +0000152inline const MethodTable* JSCell::methodTableForDestruction() const
153{
154 return &classInfo()->methodTable;
155}
156
fpizlo@apple.coma4b4cbe2013-01-12 04:47:03 +0000157inline const MethodTable* JSCell::methodTable() const
158{
oliver@apple.comb6b94a92013-01-30 01:31:37 +0000159 if (Structure* rootStructure = m_structure->structure())
160 RELEASE_ASSERT(rootStructure == rootStructure->structure());
161
fpizlo@apple.coma4b4cbe2013-01-12 04:47:03 +0000162 return &classInfo()->methodTable;
163}
164
165inline bool JSCell::inherits(const ClassInfo* info) const
166{
167 return classInfo()->isSubClassOf(info);
168}
169
fpizlo@apple.coma4b4cbe2013-01-12 04:47:03 +0000170// Fast call to get a property where we may not yet have converted the string to an
171// identifier. The first time we perform a property access with a given string, try
172// performing the property map lookup without forming an identifier. We detect this
173// case by checking whether the hash has yet been set for this string.
mhahnenberg@apple.com871ffe62013-03-15 21:52:35 +0000174ALWAYS_INLINE JSValue JSCell::fastGetOwnProperty(ExecState* exec, const String& name)
fpizlo@apple.coma4b4cbe2013-01-12 04:47:03 +0000175{
mhahnenberg@apple.com871ffe62013-03-15 21:52:35 +0000176 if (!structure()->typeInfo().overridesGetOwnPropertySlot() && !structure()->hasGetterSetterProperties()) {
177 PropertyOffset offset = name.impl()->hasHash()
ggaren@apple.com9a9a4b52013-04-18 19:32:17 +0000178 ? structure()->get(exec->vm(), Identifier(exec, name))
179 : structure()->get(exec->vm(), name);
mhahnenberg@apple.com871ffe62013-03-15 21:52:35 +0000180 if (offset != invalidOffset)
181 return asObject(this)->locationForOffset(offset)->get();
182 }
183 return JSValue();
fpizlo@apple.coma4b4cbe2013-01-12 04:47:03 +0000184}
185
186inline bool JSCell::toBoolean(ExecState* exec) const
187{
188 if (isString())
189 return static_cast<const JSString*>(this)->toBoolean();
190 return !structure()->masqueradesAsUndefined(exec->lexicalGlobalObject());
191}
192
ggaren@apple.com81c68cc2013-04-27 06:43:33 +0000193inline TriState JSCell::pureToBoolean() const
194{
195 if (isString())
196 return static_cast<const JSString*>(this)->toBoolean() ? TrueTriState : FalseTriState;
197 return MixedTriState;
198}
199
fpizlo@apple.coma4b4cbe2013-01-12 04:47:03 +0000200} // namespace JSC
201
mhahnenberg@apple.comdc3d1482013-02-01 23:10:49 +0000202#endif // JSCellInlines_h