blob: 823b2dadc8ca5d0bdc3a36e519354bf7e8ad00f0 [file] [log] [blame]
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00001// Copyright 2011 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27//
28// Review notes:
29//
ager@chromium.org32912102009-01-16 10:38:43 +000030// - The use of macros in these inline functions may seem superfluous
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000031// but it is absolutely needed to make sure gcc generates optimal
32// code. gcc is not happy when attempting to inline too deep.
33//
34
35#ifndef V8_OBJECTS_INL_H_
36#define V8_OBJECTS_INL_H_
37
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000038#include "objects.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000039#include "contexts.h"
40#include "conversions-inl.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000041#include "heap.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000042#include "isolate.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000043#include "property.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000044#include "spaces.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000045#include "v8memory.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000046
kasperl@chromium.org71affb52009-05-26 05:44:31 +000047namespace v8 {
48namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000049
50PropertyDetails::PropertyDetails(Smi* smi) {
51 value_ = smi->value();
52}
53
54
55Smi* PropertyDetails::AsSmi() {
56 return Smi::FromInt(value_);
57}
58
59
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000060PropertyDetails PropertyDetails::AsDeleted() {
ager@chromium.org378b34e2011-01-28 08:04:38 +000061 Smi* smi = Smi::FromInt(value_ | DeletedField::encode(1));
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000062 return PropertyDetails(smi);
63}
64
65
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000066#define CAST_ACCESSOR(type) \
67 type* type::cast(Object* object) { \
68 ASSERT(object->Is##type()); \
69 return reinterpret_cast<type*>(object); \
70 }
71
72
73#define INT_ACCESSORS(holder, name, offset) \
74 int holder::name() { return READ_INT_FIELD(this, offset); } \
75 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
76
77
78#define ACCESSORS(holder, name, type, offset) \
79 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000080 void holder::set_##name(type* value, WriteBarrierMode mode) { \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000081 WRITE_FIELD(this, offset, value); \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000082 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode); \
83 }
84
85
86// GC-safe accessors do not use HeapObject::GetHeap(), but access TLS instead.
87#define ACCESSORS_GCSAFE(holder, name, type, offset) \
88 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
89 void holder::set_##name(type* value, WriteBarrierMode mode) { \
90 WRITE_FIELD(this, offset, value); \
91 CONDITIONAL_WRITE_BARRIER(HEAP, this, offset, mode); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000092 }
93
94
95#define SMI_ACCESSORS(holder, name, offset) \
96 int holder::name() { \
97 Object* value = READ_FIELD(this, offset); \
98 return Smi::cast(value)->value(); \
99 } \
100 void holder::set_##name(int value) { \
101 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
102 }
103
104
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000105#define BOOL_GETTER(holder, field, name, offset) \
106 bool holder::name() { \
107 return BooleanBit::get(field(), offset); \
108 } \
109
110
111#define BOOL_ACCESSORS(holder, field, name, offset) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000112 bool holder::name() { \
113 return BooleanBit::get(field(), offset); \
114 } \
115 void holder::set_##name(bool value) { \
116 set_##field(BooleanBit::set(field(), offset, value)); \
117 }
118
119
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +0000120bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
121 // There is a constraint on the object; check.
122 if (!this->IsJSObject()) return false;
123 // Fetch the constructor function of the object.
124 Object* cons_obj = JSObject::cast(this)->map()->constructor();
125 if (!cons_obj->IsJSFunction()) return false;
126 JSFunction* fun = JSFunction::cast(cons_obj);
127 // Iterate through the chain of inheriting function templates to
128 // see if the required one occurs.
129 for (Object* type = fun->shared()->function_data();
130 type->IsFunctionTemplateInfo();
131 type = FunctionTemplateInfo::cast(type)->parent_template()) {
132 if (type == expected) return true;
133 }
134 // Didn't find the required type in the inheritance chain.
135 return false;
136}
137
138
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000139bool Object::IsSmi() {
140 return HAS_SMI_TAG(this);
141}
142
143
144bool Object::IsHeapObject() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000145 return Internals::HasHeapObjectTag(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000146}
147
148
149bool Object::IsHeapNumber() {
150 return Object::IsHeapObject()
151 && HeapObject::cast(this)->map()->instance_type() == HEAP_NUMBER_TYPE;
152}
153
154
155bool Object::IsString() {
156 return Object::IsHeapObject()
157 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
158}
159
160
ager@chromium.org870a0b62008-11-04 11:43:05 +0000161bool Object::IsSymbol() {
162 if (!this->IsHeapObject()) return false;
163 uint32_t type = HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000164 // Because the symbol tag is non-zero and no non-string types have the
165 // symbol bit set we can test for symbols with a very simple test
166 // operation.
167 ASSERT(kSymbolTag != 0);
168 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
169 return (type & kIsSymbolMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000170}
171
172
173bool Object::IsConsString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000174 if (!this->IsHeapObject()) return false;
175 uint32_t type = HeapObject::cast(this)->map()->instance_type();
176 return (type & (kIsNotStringMask | kStringRepresentationMask)) ==
177 (kStringTag | kConsStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000178}
179
180
ager@chromium.org870a0b62008-11-04 11:43:05 +0000181bool Object::IsSeqString() {
182 if (!IsString()) return false;
183 return StringShape(String::cast(this)).IsSequential();
184}
185
186
187bool Object::IsSeqAsciiString() {
188 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000189 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000190 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000191}
192
193
194bool Object::IsSeqTwoByteString() {
195 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000196 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000197 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000198}
199
200
201bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000202 if (!IsString()) return false;
203 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000204}
205
206
207bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000208 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000209 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000210 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000211}
212
213
214bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000215 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000216 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000217 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000218}
219
220
ager@chromium.org870a0b62008-11-04 11:43:05 +0000221StringShape::StringShape(String* str)
222 : type_(str->map()->instance_type()) {
223 set_valid();
224 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000225}
226
227
ager@chromium.org870a0b62008-11-04 11:43:05 +0000228StringShape::StringShape(Map* map)
229 : type_(map->instance_type()) {
230 set_valid();
231 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000232}
233
234
ager@chromium.org870a0b62008-11-04 11:43:05 +0000235StringShape::StringShape(InstanceType t)
236 : type_(static_cast<uint32_t>(t)) {
237 set_valid();
238 ASSERT((type_ & kIsNotStringMask) == kStringTag);
239}
240
241
242bool StringShape::IsSymbol() {
243 ASSERT(valid());
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000244 ASSERT(kSymbolTag != 0);
245 return (type_ & kIsSymbolMask) != 0;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000246}
247
248
ager@chromium.org5ec48922009-05-05 07:25:34 +0000249bool String::IsAsciiRepresentation() {
250 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000251 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000252}
253
254
ager@chromium.org5ec48922009-05-05 07:25:34 +0000255bool String::IsTwoByteRepresentation() {
256 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000257 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000258}
259
260
ricow@chromium.org5ad5ace2010-06-23 09:06:43 +0000261bool String::HasOnlyAsciiChars() {
262 uint32_t type = map()->instance_type();
263 return (type & kStringEncodingMask) == kAsciiStringTag ||
264 (type & kAsciiDataHintMask) == kAsciiDataHintTag;
ricow@chromium.orgaa1b6162010-03-29 07:44:58 +0000265}
266
267
ager@chromium.org870a0b62008-11-04 11:43:05 +0000268bool StringShape::IsCons() {
269 return (type_ & kStringRepresentationMask) == kConsStringTag;
270}
271
272
ager@chromium.org870a0b62008-11-04 11:43:05 +0000273bool StringShape::IsExternal() {
274 return (type_ & kStringRepresentationMask) == kExternalStringTag;
275}
276
277
278bool StringShape::IsSequential() {
279 return (type_ & kStringRepresentationMask) == kSeqStringTag;
280}
281
282
283StringRepresentationTag StringShape::representation_tag() {
284 uint32_t tag = (type_ & kStringRepresentationMask);
285 return static_cast<StringRepresentationTag>(tag);
286}
287
288
289uint32_t StringShape::full_representation_tag() {
290 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
291}
292
293
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000294STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
295 Internals::kFullStringRepresentationMask);
296
297
ager@chromium.org870a0b62008-11-04 11:43:05 +0000298bool StringShape::IsSequentialAscii() {
299 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
300}
301
302
303bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000304 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000305}
306
307
308bool StringShape::IsExternalAscii() {
309 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
310}
311
312
313bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000314 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000315}
316
317
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000318STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
319 Internals::kExternalTwoByteRepresentationTag);
320
321
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000322uc32 FlatStringReader::Get(int index) {
323 ASSERT(0 <= index && index <= length_);
324 if (is_ascii_) {
325 return static_cast<const byte*>(start_)[index];
326 } else {
327 return static_cast<const uc16*>(start_)[index];
328 }
329}
330
331
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000332bool Object::IsNumber() {
333 return IsSmi() || IsHeapNumber();
334}
335
336
337bool Object::IsByteArray() {
338 return Object::IsHeapObject()
339 && HeapObject::cast(this)->map()->instance_type() == BYTE_ARRAY_TYPE;
340}
341
342
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000343bool Object::IsExternalPixelArray() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000344 return Object::IsHeapObject() &&
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000345 HeapObject::cast(this)->map()->instance_type() ==
346 EXTERNAL_PIXEL_ARRAY_TYPE;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000347}
348
349
ager@chromium.org3811b432009-10-28 14:53:37 +0000350bool Object::IsExternalArray() {
351 if (!Object::IsHeapObject())
352 return false;
353 InstanceType instance_type =
354 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000355 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
356 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000357}
358
359
360bool Object::IsExternalByteArray() {
361 return Object::IsHeapObject() &&
362 HeapObject::cast(this)->map()->instance_type() ==
363 EXTERNAL_BYTE_ARRAY_TYPE;
364}
365
366
367bool Object::IsExternalUnsignedByteArray() {
368 return Object::IsHeapObject() &&
369 HeapObject::cast(this)->map()->instance_type() ==
370 EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE;
371}
372
373
374bool Object::IsExternalShortArray() {
375 return Object::IsHeapObject() &&
376 HeapObject::cast(this)->map()->instance_type() ==
377 EXTERNAL_SHORT_ARRAY_TYPE;
378}
379
380
381bool Object::IsExternalUnsignedShortArray() {
382 return Object::IsHeapObject() &&
383 HeapObject::cast(this)->map()->instance_type() ==
384 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE;
385}
386
387
388bool Object::IsExternalIntArray() {
389 return Object::IsHeapObject() &&
390 HeapObject::cast(this)->map()->instance_type() ==
391 EXTERNAL_INT_ARRAY_TYPE;
392}
393
394
395bool Object::IsExternalUnsignedIntArray() {
396 return Object::IsHeapObject() &&
397 HeapObject::cast(this)->map()->instance_type() ==
398 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE;
399}
400
401
402bool Object::IsExternalFloatArray() {
403 return Object::IsHeapObject() &&
404 HeapObject::cast(this)->map()->instance_type() ==
405 EXTERNAL_FLOAT_ARRAY_TYPE;
406}
407
408
lrn@chromium.org303ada72010-10-27 09:33:13 +0000409bool MaybeObject::IsFailure() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000410 return HAS_FAILURE_TAG(this);
411}
412
413
lrn@chromium.org303ada72010-10-27 09:33:13 +0000414bool MaybeObject::IsRetryAfterGC() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000415 return HAS_FAILURE_TAG(this)
416 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
417}
418
419
lrn@chromium.org303ada72010-10-27 09:33:13 +0000420bool MaybeObject::IsOutOfMemory() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000421 return HAS_FAILURE_TAG(this)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000422 && Failure::cast(this)->IsOutOfMemoryException();
ager@chromium.org7c537e22008-10-16 08:43:32 +0000423}
424
425
lrn@chromium.org303ada72010-10-27 09:33:13 +0000426bool MaybeObject::IsException() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000427 return this == Failure::Exception();
428}
429
430
lrn@chromium.org303ada72010-10-27 09:33:13 +0000431bool MaybeObject::IsTheHole() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000432 return !IsFailure() && ToObjectUnchecked()->IsTheHole();
lrn@chromium.org303ada72010-10-27 09:33:13 +0000433}
434
435
436Failure* Failure::cast(MaybeObject* obj) {
437 ASSERT(HAS_FAILURE_TAG(obj));
438 return reinterpret_cast<Failure*>(obj);
439}
440
441
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000442bool Object::IsJSObject() {
443 return IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000444 && HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000445}
446
447
ager@chromium.org32912102009-01-16 10:38:43 +0000448bool Object::IsJSContextExtensionObject() {
449 return IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000450 && (HeapObject::cast(this)->map()->instance_type() ==
451 JS_CONTEXT_EXTENSION_OBJECT_TYPE);
ager@chromium.org32912102009-01-16 10:38:43 +0000452}
453
454
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000455bool Object::IsMap() {
456 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000457 && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000458}
459
460
461bool Object::IsFixedArray() {
462 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000463 && HeapObject::cast(this)->map()->instance_type() == FIXED_ARRAY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000464}
465
466
467bool Object::IsDescriptorArray() {
468 return IsFixedArray();
469}
470
471
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000472bool Object::IsDeoptimizationInputData() {
473 // Must be a fixed array.
474 if (!IsFixedArray()) return false;
475
476 // There's no sure way to detect the difference between a fixed array and
477 // a deoptimization data array. Since this is used for asserts we can
478 // check that the length is zero or else the fixed size plus a multiple of
479 // the entry size.
480 int length = FixedArray::cast(this)->length();
481 if (length == 0) return true;
482
483 length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
484 return length >= 0 &&
485 length % DeoptimizationInputData::kDeoptEntrySize == 0;
486}
487
488
489bool Object::IsDeoptimizationOutputData() {
490 if (!IsFixedArray()) return false;
491 // There's actually no way to see the difference between a fixed array and
492 // a deoptimization data array. Since this is used for asserts we can check
493 // that the length is plausible though.
494 if (FixedArray::cast(this)->length() % 2 != 0) return false;
495 return true;
496}
497
498
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000499bool Object::IsContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000500 if (Object::IsHeapObject()) {
501 Heap* heap = HeapObject::cast(this)->GetHeap();
502 return (HeapObject::cast(this)->map() == heap->context_map() ||
503 HeapObject::cast(this)->map() == heap->catch_context_map() ||
504 HeapObject::cast(this)->map() == heap->global_context_map());
505 }
506 return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000507}
508
509
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000510bool Object::IsCatchContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000511 return Object::IsHeapObject() &&
512 HeapObject::cast(this)->map() ==
513 HeapObject::cast(this)->GetHeap()->catch_context_map();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000514}
515
516
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000517bool Object::IsGlobalContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000518 return Object::IsHeapObject() &&
519 HeapObject::cast(this)->map() ==
520 HeapObject::cast(this)->GetHeap()->global_context_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000521}
522
523
524bool Object::IsJSFunction() {
525 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000526 && HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000527}
528
529
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000530template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000531 return obj->IsJSFunction();
532}
533
534
535bool Object::IsCode() {
536 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000537 && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000538}
539
540
541bool Object::IsOddball() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000542 ASSERT(HEAP->is_safe_to_read_maps());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000543 return Object::IsHeapObject()
544 && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE;
545}
546
547
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000548bool Object::IsJSGlobalPropertyCell() {
549 return Object::IsHeapObject()
550 && HeapObject::cast(this)->map()->instance_type()
551 == JS_GLOBAL_PROPERTY_CELL_TYPE;
552}
553
554
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000555bool Object::IsSharedFunctionInfo() {
556 return Object::IsHeapObject() &&
557 (HeapObject::cast(this)->map()->instance_type() ==
558 SHARED_FUNCTION_INFO_TYPE);
559}
560
561
562bool Object::IsJSValue() {
563 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000564 && HeapObject::cast(this)->map()->instance_type() == JS_VALUE_TYPE;
565}
566
567
568bool Object::IsJSMessageObject() {
569 return Object::IsHeapObject()
570 && (HeapObject::cast(this)->map()->instance_type() ==
571 JS_MESSAGE_OBJECT_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000572}
573
574
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000575bool Object::IsStringWrapper() {
576 return IsJSValue() && JSValue::cast(this)->value()->IsString();
577}
578
579
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000580bool Object::IsProxy() {
581 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000582 && HeapObject::cast(this)->map()->instance_type() == PROXY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000583}
584
585
586bool Object::IsBoolean() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000587 return IsOddball() &&
588 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000589}
590
591
592bool Object::IsJSArray() {
593 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000594 && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000595}
596
597
ager@chromium.org236ad962008-09-25 09:45:57 +0000598bool Object::IsJSRegExp() {
599 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000600 && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
ager@chromium.org236ad962008-09-25 09:45:57 +0000601}
602
603
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000604template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000605 return obj->IsJSArray();
606}
607
608
609bool Object::IsHashTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000610 return Object::IsHeapObject() &&
611 HeapObject::cast(this)->map() ==
612 HeapObject::cast(this)->GetHeap()->hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000613}
614
615
616bool Object::IsDictionary() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000617 return IsHashTable() && this !=
618 HeapObject::cast(this)->GetHeap()->symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000619}
620
621
622bool Object::IsSymbolTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000623 return IsHashTable() && this ==
624 HeapObject::cast(this)->GetHeap()->raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000625}
626
627
ager@chromium.orgac091b72010-05-05 07:34:42 +0000628bool Object::IsJSFunctionResultCache() {
629 if (!IsFixedArray()) return false;
630 FixedArray* self = FixedArray::cast(this);
631 int length = self->length();
632 if (length < JSFunctionResultCache::kEntriesIndex) return false;
633 if ((length - JSFunctionResultCache::kEntriesIndex)
634 % JSFunctionResultCache::kEntrySize != 0) {
635 return false;
636 }
637#ifdef DEBUG
638 reinterpret_cast<JSFunctionResultCache*>(this)->JSFunctionResultCacheVerify();
639#endif
640 return true;
641}
642
643
ricow@chromium.org65fae842010-08-25 15:26:24 +0000644bool Object::IsNormalizedMapCache() {
645 if (!IsFixedArray()) return false;
646 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
647 return false;
648 }
649#ifdef DEBUG
650 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
651#endif
652 return true;
653}
654
655
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000656bool Object::IsCompilationCacheTable() {
657 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000658}
659
660
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000661bool Object::IsCodeCacheHashTable() {
662 return IsHashTable();
663}
664
665
ager@chromium.org236ad962008-09-25 09:45:57 +0000666bool Object::IsMapCache() {
667 return IsHashTable();
668}
669
670
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000671bool Object::IsPrimitive() {
672 return IsOddball() || IsNumber() || IsString();
673}
674
675
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000676bool Object::IsJSGlobalProxy() {
677 bool result = IsHeapObject() &&
678 (HeapObject::cast(this)->map()->instance_type() ==
679 JS_GLOBAL_PROXY_TYPE);
680 ASSERT(!result || IsAccessCheckNeeded());
681 return result;
682}
683
684
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000685bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000686 if (!IsHeapObject()) return false;
687
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000688 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000689 return type == JS_GLOBAL_OBJECT_TYPE ||
690 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000691}
692
693
694bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000695 return IsHeapObject() &&
696 (HeapObject::cast(this)->map()->instance_type() ==
697 JS_GLOBAL_OBJECT_TYPE);
698}
699
700
701bool Object::IsJSBuiltinsObject() {
702 return IsHeapObject() &&
703 (HeapObject::cast(this)->map()->instance_type() ==
704 JS_BUILTINS_OBJECT_TYPE);
705}
706
707
708bool Object::IsUndetectableObject() {
709 return IsHeapObject()
710 && HeapObject::cast(this)->map()->is_undetectable();
711}
712
713
714bool Object::IsAccessCheckNeeded() {
715 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000716 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000717}
718
719
720bool Object::IsStruct() {
721 if (!IsHeapObject()) return false;
722 switch (HeapObject::cast(this)->map()->instance_type()) {
723#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
724 STRUCT_LIST(MAKE_STRUCT_CASE)
725#undef MAKE_STRUCT_CASE
726 default: return false;
727 }
728}
729
730
731#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
732 bool Object::Is##Name() { \
733 return Object::IsHeapObject() \
734 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
735 }
736 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
737#undef MAKE_STRUCT_PREDICATE
738
739
740bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000741 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000742}
743
744
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000745bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000746 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
747}
748
749
750bool Object::IsTheHole() {
751 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000752}
753
754
755bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000756 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000757}
758
759
760bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000761 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000762}
763
764
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000765bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000766 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000767}
768
769
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000770double Object::Number() {
771 ASSERT(IsNumber());
772 return IsSmi()
773 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
774 : reinterpret_cast<HeapNumber*>(this)->value();
775}
776
777
lrn@chromium.org303ada72010-10-27 09:33:13 +0000778MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000779 if (IsSmi()) return this;
780 if (IsHeapNumber()) {
781 double value = HeapNumber::cast(this)->value();
782 int int_value = FastD2I(value);
783 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
784 return Smi::FromInt(int_value);
785 }
786 }
787 return Failure::Exception();
788}
789
790
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000791bool Object::HasSpecificClassOf(String* name) {
792 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
793}
794
795
lrn@chromium.org303ada72010-10-27 09:33:13 +0000796MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000797 // GetElement can trigger a getter which can cause allocation.
798 // This was not always the case. This ASSERT is here to catch
799 // leftover incorrect uses.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000800 ASSERT(HEAP->IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000801 return GetElementWithReceiver(this, index);
802}
803
804
lrn@chromium.org303ada72010-10-27 09:33:13 +0000805Object* Object::GetElementNoExceptionThrown(uint32_t index) {
806 MaybeObject* maybe = GetElementWithReceiver(this, index);
807 ASSERT(!maybe->IsFailure());
808 Object* result = NULL; // Initialization to please compiler.
809 maybe->ToObject(&result);
810 return result;
811}
812
813
814MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000815 PropertyAttributes attributes;
816 return GetPropertyWithReceiver(this, key, &attributes);
817}
818
819
lrn@chromium.org303ada72010-10-27 09:33:13 +0000820MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000821 return GetPropertyWithReceiver(this, key, attributes);
822}
823
824
825#define FIELD_ADDR(p, offset) \
826 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
827
828#define READ_FIELD(p, offset) \
829 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
830
831#define WRITE_FIELD(p, offset, value) \
832 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
833
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000834// TODO(isolates): Pass heap in to these macros.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000835#define WRITE_BARRIER(object, offset) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000836 object->GetHeap()->RecordWrite(object->address(), offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000837
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000838// CONDITIONAL_WRITE_BARRIER must be issued after the actual
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000839// write due to the assert validating the written value.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000840#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, mode) \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000841 if (mode == UPDATE_WRITE_BARRIER) { \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000842 heap->RecordWrite(object->address(), offset); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000843 } else { \
844 ASSERT(mode == SKIP_WRITE_BARRIER); \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000845 ASSERT(heap->InNewSpace(object) || \
846 !heap->InNewSpace(READ_FIELD(object, offset)) || \
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000847 Page::FromAddress(object->address())-> \
848 IsRegionDirty(object->address() + offset)); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000849 }
850
lrn@chromium.org7516f052011-03-30 08:52:27 +0000851#ifndef V8_TARGET_ARCH_MIPS
852 #define READ_DOUBLE_FIELD(p, offset) \
853 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
854#else // V8_TARGET_ARCH_MIPS
855 // Prevent gcc from using load-double (mips ldc1) on (possibly)
856 // non-64-bit aligned HeapNumber::value.
857 static inline double read_double_field(HeapNumber* p, int offset) {
858 union conversion {
859 double d;
860 uint32_t u[2];
861 } c;
862 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
863 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
864 return c.d;
865 }
866 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
867#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000868
lrn@chromium.org7516f052011-03-30 08:52:27 +0000869
870#ifndef V8_TARGET_ARCH_MIPS
871 #define WRITE_DOUBLE_FIELD(p, offset, value) \
872 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
873#else // V8_TARGET_ARCH_MIPS
874 // Prevent gcc from using store-double (mips sdc1) on (possibly)
875 // non-64-bit aligned HeapNumber::value.
876 static inline void write_double_field(HeapNumber* p, int offset,
877 double value) {
878 union conversion {
879 double d;
880 uint32_t u[2];
881 } c;
882 c.d = value;
883 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
884 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
885 }
886 #define WRITE_DOUBLE_FIELD(p, offset, value) \
887 write_double_field(p, offset, value)
888#endif // V8_TARGET_ARCH_MIPS
889
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000890
891#define READ_INT_FIELD(p, offset) \
892 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
893
894#define WRITE_INT_FIELD(p, offset, value) \
895 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
896
ager@chromium.org3e875802009-06-29 08:26:34 +0000897#define READ_INTPTR_FIELD(p, offset) \
898 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
899
900#define WRITE_INTPTR_FIELD(p, offset, value) \
901 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
902
ager@chromium.org7c537e22008-10-16 08:43:32 +0000903#define READ_UINT32_FIELD(p, offset) \
904 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
905
906#define WRITE_UINT32_FIELD(p, offset, value) \
907 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
908
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000909#define READ_SHORT_FIELD(p, offset) \
910 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
911
912#define WRITE_SHORT_FIELD(p, offset, value) \
913 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
914
915#define READ_BYTE_FIELD(p, offset) \
916 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
917
918#define WRITE_BYTE_FIELD(p, offset, value) \
919 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
920
921
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000922Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
923 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000924}
925
926
927int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000928 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000929}
930
931
932Smi* Smi::FromInt(int value) {
933 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000934 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000935 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000936 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000937 return reinterpret_cast<Smi*>(tagged_value);
938}
939
940
941Smi* Smi::FromIntptr(intptr_t value) {
942 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000943 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
944 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000945}
946
947
948Failure::Type Failure::type() const {
949 return static_cast<Type>(value() & kFailureTypeTagMask);
950}
951
952
953bool Failure::IsInternalError() const {
954 return type() == INTERNAL_ERROR;
955}
956
957
958bool Failure::IsOutOfMemoryException() const {
959 return type() == OUT_OF_MEMORY_EXCEPTION;
960}
961
962
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000963AllocationSpace Failure::allocation_space() const {
964 ASSERT_EQ(RETRY_AFTER_GC, type());
965 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
966 & kSpaceTagMask);
967}
968
969
970Failure* Failure::InternalError() {
971 return Construct(INTERNAL_ERROR);
972}
973
974
975Failure* Failure::Exception() {
976 return Construct(EXCEPTION);
977}
978
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000979
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000980Failure* Failure::OutOfMemoryException() {
981 return Construct(OUT_OF_MEMORY_EXCEPTION);
982}
983
984
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000985intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000986 return static_cast<intptr_t>(
987 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000988}
989
990
whesse@chromium.org4a5224e2010-10-20 12:37:07 +0000991Failure* Failure::RetryAfterGC() {
992 return RetryAfterGC(NEW_SPACE);
993}
994
995
996Failure* Failure::RetryAfterGC(AllocationSpace space) {
997 ASSERT((space & ~kSpaceTagMask) == 0);
998 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000999}
1000
1001
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001002Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001003 uintptr_t info =
1004 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001005 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001006 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001007}
1008
1009
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001010bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001011#ifdef DEBUG
1012 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1013#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001014
1015#ifdef V8_TARGET_ARCH_X64
1016 // To be representable as a long smi, the value must be a 32-bit integer.
1017 bool result = (value == static_cast<int32_t>(value));
1018#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001019 // To be representable as an tagged small integer, the two
1020 // most-significant bits of 'value' must be either 00 or 11 due to
1021 // sign-extension. To check this we add 01 to the two
1022 // most-significant bits, and check if the most-significant bit is 0
1023 //
1024 // CAUTION: The original code below:
1025 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1026 // may lead to incorrect results according to the C language spec, and
1027 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1028 // compiler may produce undefined results in case of signed integer
1029 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001030 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001031#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001032 ASSERT(result == in_range);
1033 return result;
1034}
1035
1036
kasper.lund7276f142008-07-30 08:49:36 +00001037MapWord MapWord::FromMap(Map* map) {
1038 return MapWord(reinterpret_cast<uintptr_t>(map));
1039}
1040
1041
1042Map* MapWord::ToMap() {
1043 return reinterpret_cast<Map*>(value_);
1044}
1045
1046
1047bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001048 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001049}
1050
1051
1052MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001053 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1054 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001055}
1056
1057
1058HeapObject* MapWord::ToForwardingAddress() {
1059 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001060 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001061}
1062
1063
1064bool MapWord::IsMarked() {
1065 return (value_ & kMarkingMask) == 0;
1066}
1067
1068
1069void MapWord::SetMark() {
1070 value_ &= ~kMarkingMask;
1071}
1072
1073
1074void MapWord::ClearMark() {
1075 value_ |= kMarkingMask;
1076}
1077
1078
1079bool MapWord::IsOverflowed() {
1080 return (value_ & kOverflowMask) != 0;
1081}
1082
1083
1084void MapWord::SetOverflow() {
1085 value_ |= kOverflowMask;
1086}
1087
1088
1089void MapWord::ClearOverflow() {
1090 value_ &= ~kOverflowMask;
1091}
1092
1093
1094MapWord MapWord::EncodeAddress(Address map_address, int offset) {
1095 // Offset is the distance in live bytes from the first live object in the
1096 // same page. The offset between two objects in the same page should not
1097 // exceed the object area size of a page.
1098 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
1099
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001100 uintptr_t compact_offset = offset >> kObjectAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001101 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
1102
1103 Page* map_page = Page::FromAddress(map_address);
1104 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
1105
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001106 uintptr_t map_page_offset =
1107 map_page->Offset(map_address) >> kMapAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001108
1109 uintptr_t encoding =
1110 (compact_offset << kForwardingOffsetShift) |
1111 (map_page_offset << kMapPageOffsetShift) |
1112 (map_page->mc_page_index << kMapPageIndexShift);
1113 return MapWord(encoding);
1114}
1115
1116
1117Address MapWord::DecodeMapAddress(MapSpace* map_space) {
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001118 int map_page_index =
1119 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
kasper.lund7276f142008-07-30 08:49:36 +00001120 ASSERT_MAP_PAGE_INDEX(map_page_index);
1121
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001122 int map_page_offset = static_cast<int>(
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001123 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift) <<
1124 kMapAlignmentBits);
kasper.lund7276f142008-07-30 08:49:36 +00001125
1126 return (map_space->PageAddress(map_page_index) + map_page_offset);
1127}
1128
1129
1130int MapWord::DecodeOffset() {
1131 // The offset field is represented in the kForwardingOffsetBits
1132 // most-significant bits.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001133 uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
1134 ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize));
1135 return static_cast<int>(offset);
kasper.lund7276f142008-07-30 08:49:36 +00001136}
1137
1138
1139MapWord MapWord::FromEncodedAddress(Address address) {
1140 return MapWord(reinterpret_cast<uintptr_t>(address));
1141}
1142
1143
1144Address MapWord::ToEncodedAddress() {
1145 return reinterpret_cast<Address>(value_);
1146}
1147
1148
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001149#ifdef DEBUG
1150void HeapObject::VerifyObjectField(int offset) {
1151 VerifyPointer(READ_FIELD(this, offset));
1152}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001153
1154void HeapObject::VerifySmiField(int offset) {
1155 ASSERT(READ_FIELD(this, offset)->IsSmi());
1156}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001157#endif
1158
1159
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001160Heap* HeapObject::GetHeap() {
1161 // During GC, the map pointer in HeapObject is used in various ways that
1162 // prevent us from retrieving Heap from the map.
1163 // Assert that we are not in GC, implement GC code in a way that it doesn't
1164 // pull heap from the map.
1165 ASSERT(HEAP->is_safe_to_read_maps());
1166 return map()->heap();
1167}
1168
1169
1170Isolate* HeapObject::GetIsolate() {
1171 return GetHeap()->isolate();
1172}
1173
1174
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001175Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001176 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001177}
1178
1179
1180void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001181 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001182}
1183
1184
kasper.lund7276f142008-07-30 08:49:36 +00001185MapWord HeapObject::map_word() {
1186 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1187}
1188
1189
1190void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001191 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001192 // here.
1193 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1194}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001195
1196
1197HeapObject* HeapObject::FromAddress(Address address) {
1198 ASSERT_TAG_ALIGNED(address);
1199 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1200}
1201
1202
1203Address HeapObject::address() {
1204 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1205}
1206
1207
1208int HeapObject::Size() {
1209 return SizeFromMap(map());
1210}
1211
1212
1213void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1214 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1215 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1216}
1217
1218
1219void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1220 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1221}
1222
1223
kasper.lund7276f142008-07-30 08:49:36 +00001224bool HeapObject::IsMarked() {
1225 return map_word().IsMarked();
1226}
1227
1228
1229void HeapObject::SetMark() {
1230 ASSERT(!IsMarked());
1231 MapWord first_word = map_word();
1232 first_word.SetMark();
1233 set_map_word(first_word);
1234}
1235
1236
1237void HeapObject::ClearMark() {
1238 ASSERT(IsMarked());
1239 MapWord first_word = map_word();
1240 first_word.ClearMark();
1241 set_map_word(first_word);
1242}
1243
1244
1245bool HeapObject::IsOverflowed() {
1246 return map_word().IsOverflowed();
1247}
1248
1249
1250void HeapObject::SetOverflow() {
1251 MapWord first_word = map_word();
1252 first_word.SetOverflow();
1253 set_map_word(first_word);
1254}
1255
1256
1257void HeapObject::ClearOverflow() {
1258 ASSERT(IsOverflowed());
1259 MapWord first_word = map_word();
1260 first_word.ClearOverflow();
1261 set_map_word(first_word);
1262}
1263
1264
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001265double HeapNumber::value() {
1266 return READ_DOUBLE_FIELD(this, kValueOffset);
1267}
1268
1269
1270void HeapNumber::set_value(double value) {
1271 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1272}
1273
1274
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001275int HeapNumber::get_exponent() {
1276 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1277 kExponentShift) - kExponentBias;
1278}
1279
1280
1281int HeapNumber::get_sign() {
1282 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1283}
1284
1285
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001286ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001287
1288
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001289HeapObject* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001290 Object* array = READ_FIELD(this, kElementsOffset);
1291 // In the assert below Dictionary is covered under FixedArray.
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001292 ASSERT(array->IsFixedArray() || array->IsExternalArray());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001293 return reinterpret_cast<HeapObject*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001294}
1295
1296
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001297void JSObject::set_elements(HeapObject* value, WriteBarrierMode mode) {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001298 ASSERT(map()->has_fast_elements() ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001299 (value->map() == GetHeap()->fixed_array_map() ||
1300 value->map() == GetHeap()->fixed_cow_array_map()));
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001301 // In the assert below Dictionary is covered under FixedArray.
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001302 ASSERT(value->IsFixedArray() || value->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001303 WRITE_FIELD(this, kElementsOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001304 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001305}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001306
1307
1308void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001309 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1310 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001311}
1312
1313
1314void JSObject::initialize_elements() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001315 ASSERT(map()->has_fast_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001316 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1317 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001318}
1319
1320
lrn@chromium.org303ada72010-10-27 09:33:13 +00001321MaybeObject* JSObject::ResetElements() {
1322 Object* obj;
1323 { MaybeObject* maybe_obj = map()->GetFastElementsMap();
1324 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1325 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001326 set_map(Map::cast(obj));
1327 initialize_elements();
1328 return this;
1329}
1330
1331
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001332ACCESSORS(Oddball, to_string, String, kToStringOffset)
1333ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1334
1335
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001336byte Oddball::kind() {
1337 return READ_BYTE_FIELD(this, kKindOffset);
1338}
1339
1340
1341void Oddball::set_kind(byte value) {
1342 WRITE_BYTE_FIELD(this, kKindOffset, value);
1343}
1344
1345
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001346Object* JSGlobalPropertyCell::value() {
1347 return READ_FIELD(this, kValueOffset);
1348}
1349
1350
1351void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1352 // The write barrier is not used for global property cells.
1353 ASSERT(!val->IsJSGlobalPropertyCell());
1354 WRITE_FIELD(this, kValueOffset, val);
1355}
1356
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001357
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001358int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001359 InstanceType type = map()->instance_type();
1360 // Check for the most common kind of JavaScript object before
1361 // falling into the generic switch. This speeds up the internal
1362 // field operations considerably on average.
1363 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1364 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001365 case JS_GLOBAL_PROXY_TYPE:
1366 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001367 case JS_GLOBAL_OBJECT_TYPE:
1368 return JSGlobalObject::kSize;
1369 case JS_BUILTINS_OBJECT_TYPE:
1370 return JSBuiltinsObject::kSize;
1371 case JS_FUNCTION_TYPE:
1372 return JSFunction::kSize;
1373 case JS_VALUE_TYPE:
1374 return JSValue::kSize;
1375 case JS_ARRAY_TYPE:
1376 return JSValue::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001377 case JS_REGEXP_TYPE:
1378 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001379 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001380 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001381 case JS_MESSAGE_OBJECT_TYPE:
1382 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001383 default:
1384 UNREACHABLE();
1385 return 0;
1386 }
1387}
1388
1389
1390int JSObject::GetInternalFieldCount() {
1391 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001392 // Make sure to adjust for the number of in-object properties. These
1393 // properties do contribute to the size, but are not internal fields.
1394 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1395 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001396}
1397
1398
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001399int JSObject::GetInternalFieldOffset(int index) {
1400 ASSERT(index < GetInternalFieldCount() && index >= 0);
1401 return GetHeaderSize() + (kPointerSize * index);
1402}
1403
1404
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001405Object* JSObject::GetInternalField(int index) {
1406 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001407 // Internal objects do follow immediately after the header, whereas in-object
1408 // properties are at the end of the object. Therefore there is no need
1409 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001410 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1411}
1412
1413
1414void JSObject::SetInternalField(int index, Object* value) {
1415 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001416 // Internal objects do follow immediately after the header, whereas in-object
1417 // properties are at the end of the object. Therefore there is no need
1418 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001419 int offset = GetHeaderSize() + (kPointerSize * index);
1420 WRITE_FIELD(this, offset, value);
1421 WRITE_BARRIER(this, offset);
1422}
1423
1424
ager@chromium.org7c537e22008-10-16 08:43:32 +00001425// Access fast-case object properties at index. The use of these routines
1426// is needed to correctly distinguish between properties stored in-object and
1427// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001428Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001429 // Adjust for the number of properties stored in the object.
1430 index -= map()->inobject_properties();
1431 if (index < 0) {
1432 int offset = map()->instance_size() + (index * kPointerSize);
1433 return READ_FIELD(this, offset);
1434 } else {
1435 ASSERT(index < properties()->length());
1436 return properties()->get(index);
1437 }
1438}
1439
1440
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001441Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001442 // Adjust for the number of properties stored in the object.
1443 index -= map()->inobject_properties();
1444 if (index < 0) {
1445 int offset = map()->instance_size() + (index * kPointerSize);
1446 WRITE_FIELD(this, offset, value);
1447 WRITE_BARRIER(this, offset);
1448 } else {
1449 ASSERT(index < properties()->length());
1450 properties()->set(index, value);
1451 }
1452 return value;
1453}
1454
1455
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001456int JSObject::GetInObjectPropertyOffset(int index) {
1457 // Adjust for the number of properties stored in the object.
1458 index -= map()->inobject_properties();
1459 ASSERT(index < 0);
1460 return map()->instance_size() + (index * kPointerSize);
1461}
1462
1463
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001464Object* JSObject::InObjectPropertyAt(int index) {
1465 // Adjust for the number of properties stored in the object.
1466 index -= map()->inobject_properties();
1467 ASSERT(index < 0);
1468 int offset = map()->instance_size() + (index * kPointerSize);
1469 return READ_FIELD(this, offset);
1470}
1471
1472
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001473Object* JSObject::InObjectPropertyAtPut(int index,
1474 Object* value,
1475 WriteBarrierMode mode) {
1476 // Adjust for the number of properties stored in the object.
1477 index -= map()->inobject_properties();
1478 ASSERT(index < 0);
1479 int offset = map()->instance_size() + (index * kPointerSize);
1480 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001481 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001482 return value;
1483}
1484
1485
1486
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001487void JSObject::InitializeBody(int object_size, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001488 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001489 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001490 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001491 }
1492}
1493
1494
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001495bool JSObject::HasFastProperties() {
1496 return !properties()->IsDictionary();
1497}
1498
1499
1500int JSObject::MaxFastProperties() {
1501 // Allow extra fast properties if the object has more than
1502 // kMaxFastProperties in-object properties. When this is the case,
1503 // it is very unlikely that the object is being used as a dictionary
1504 // and there is a good chance that allowing more map transitions
1505 // will be worth it.
1506 return Max(map()->inobject_properties(), kMaxFastProperties);
1507}
1508
1509
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001510void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001511 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001512 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001513 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001514 }
1515}
1516
1517
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001518bool Object::ToArrayIndex(uint32_t* index) {
1519 if (IsSmi()) {
1520 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001521 if (value < 0) return false;
1522 *index = value;
1523 return true;
1524 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001525 if (IsHeapNumber()) {
1526 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001527 uint32_t uint_value = static_cast<uint32_t>(value);
1528 if (value == static_cast<double>(uint_value)) {
1529 *index = uint_value;
1530 return true;
1531 }
1532 }
1533 return false;
1534}
1535
1536
1537bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1538 if (!this->IsJSValue()) return false;
1539
1540 JSValue* js_value = JSValue::cast(this);
1541 if (!js_value->value()->IsString()) return false;
1542
1543 String* str = String::cast(js_value->value());
1544 if (index >= (uint32_t)str->length()) return false;
1545
1546 return true;
1547}
1548
1549
1550Object* FixedArray::get(int index) {
1551 ASSERT(index >= 0 && index < this->length());
1552 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1553}
1554
1555
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001556void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001557 ASSERT(map() != HEAP->fixed_cow_array_map());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001558 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1559 int offset = kHeaderSize + index * kPointerSize;
1560 WRITE_FIELD(this, offset, value);
1561}
1562
1563
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001564void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001565 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001566 ASSERT(index >= 0 && index < this->length());
1567 int offset = kHeaderSize + index * kPointerSize;
1568 WRITE_FIELD(this, offset, value);
1569 WRITE_BARRIER(this, offset);
1570}
1571
1572
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001573WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001574 if (GetHeap()->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001575 return UPDATE_WRITE_BARRIER;
1576}
1577
1578
1579void FixedArray::set(int index,
1580 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001581 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001582 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001583 ASSERT(index >= 0 && index < this->length());
1584 int offset = kHeaderSize + index * kPointerSize;
1585 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001586 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001587}
1588
1589
1590void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001591 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001592 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001593 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001594 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1595}
1596
1597
1598void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001599 ASSERT(map() != HEAP->fixed_cow_array_map());
1600 set_undefined(GetHeap(), index);
1601}
1602
1603
1604void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001605 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001606 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001607 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001608 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001609}
1610
1611
ager@chromium.org236ad962008-09-25 09:45:57 +00001612void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001613 set_null(GetHeap(), index);
1614}
1615
1616
1617void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001618 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001619 ASSERT(!heap->InNewSpace(heap->null_value()));
1620 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001621}
1622
1623
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001624void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001625 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001626 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001627 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1628 WRITE_FIELD(this,
1629 kHeaderSize + index * kPointerSize,
1630 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001631}
1632
1633
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001634void FixedArray::set_unchecked(int index, Smi* value) {
1635 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1636 int offset = kHeaderSize + index * kPointerSize;
1637 WRITE_FIELD(this, offset, value);
1638}
1639
1640
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001641void FixedArray::set_unchecked(Heap* heap,
1642 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001643 Object* value,
1644 WriteBarrierMode mode) {
1645 int offset = kHeaderSize + index * kPointerSize;
1646 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001647 CONDITIONAL_WRITE_BARRIER(heap, this, offset, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001648}
1649
1650
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001651void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001652 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001653 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1654 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001655}
1656
1657
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001658Object** FixedArray::data_start() {
1659 return HeapObject::RawField(this, kHeaderSize);
1660}
1661
1662
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001663bool DescriptorArray::IsEmpty() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001664 ASSERT(this->length() > kFirstIndex ||
1665 this == HEAP->empty_descriptor_array());
1666 return length() <= kFirstIndex;
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001667}
1668
1669
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001670void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1671 Object* tmp = array->get(first);
1672 fast_set(array, first, array->get(second));
1673 fast_set(array, second, tmp);
1674}
1675
1676
1677int DescriptorArray::Search(String* name) {
1678 SLOW_ASSERT(IsSortedNoDuplicates());
1679
1680 // Check for empty descriptor array.
1681 int nof = number_of_descriptors();
1682 if (nof == 0) return kNotFound;
1683
1684 // Fast case: do linear search for small arrays.
1685 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001686 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001687 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001688 }
1689
1690 // Slow case: perform binary search.
1691 return BinarySearch(name, 0, nof - 1);
1692}
1693
1694
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001695int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001696 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001697 if (number == DescriptorLookupCache::kAbsent) {
1698 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001699 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001700 }
1701 return number;
1702}
1703
1704
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001705String* DescriptorArray::GetKey(int descriptor_number) {
1706 ASSERT(descriptor_number < number_of_descriptors());
1707 return String::cast(get(ToKeyIndex(descriptor_number)));
1708}
1709
1710
1711Object* DescriptorArray::GetValue(int descriptor_number) {
1712 ASSERT(descriptor_number < number_of_descriptors());
1713 return GetContentArray()->get(ToValueIndex(descriptor_number));
1714}
1715
1716
1717Smi* DescriptorArray::GetDetails(int descriptor_number) {
1718 ASSERT(descriptor_number < number_of_descriptors());
1719 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1720}
1721
1722
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001723PropertyType DescriptorArray::GetType(int descriptor_number) {
1724 ASSERT(descriptor_number < number_of_descriptors());
1725 return PropertyDetails(GetDetails(descriptor_number)).type();
1726}
1727
1728
1729int DescriptorArray::GetFieldIndex(int descriptor_number) {
1730 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1731}
1732
1733
1734JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1735 return JSFunction::cast(GetValue(descriptor_number));
1736}
1737
1738
1739Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1740 ASSERT(GetType(descriptor_number) == CALLBACKS);
1741 return GetValue(descriptor_number);
1742}
1743
1744
1745AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1746 ASSERT(GetType(descriptor_number) == CALLBACKS);
1747 Proxy* p = Proxy::cast(GetCallbacksObject(descriptor_number));
1748 return reinterpret_cast<AccessorDescriptor*>(p->proxy());
1749}
1750
1751
1752bool DescriptorArray::IsProperty(int descriptor_number) {
1753 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1754}
1755
1756
1757bool DescriptorArray::IsTransition(int descriptor_number) {
1758 PropertyType t = GetType(descriptor_number);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001759 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION ||
1760 t == EXTERNAL_ARRAY_TRANSITION;
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001761}
1762
1763
1764bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1765 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1766}
1767
1768
1769bool DescriptorArray::IsDontEnum(int descriptor_number) {
1770 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1771}
1772
1773
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001774void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1775 desc->Init(GetKey(descriptor_number),
1776 GetValue(descriptor_number),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001777 PropertyDetails(GetDetails(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001778}
1779
1780
1781void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1782 // Range check.
1783 ASSERT(descriptor_number < number_of_descriptors());
1784
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001785 // Make sure none of the elements in desc are in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001786 ASSERT(!HEAP->InNewSpace(desc->GetKey()));
1787 ASSERT(!HEAP->InNewSpace(desc->GetValue()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001788
1789 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1790 FixedArray* content_array = GetContentArray();
1791 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1792 fast_set(content_array, ToDetailsIndex(descriptor_number),
1793 desc->GetDetails().AsSmi());
1794}
1795
1796
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001797void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1798 Descriptor desc;
1799 src->Get(src_index, &desc);
1800 Set(index, &desc);
1801}
1802
1803
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001804void DescriptorArray::Swap(int first, int second) {
1805 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1806 FixedArray* content_array = GetContentArray();
1807 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1808 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1809}
1810
1811
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001812template<typename Shape, typename Key>
1813int HashTable<Shape, Key>::FindEntry(Key key) {
1814 return FindEntry(GetIsolate(), key);
1815}
1816
1817
1818// Find entry for key otherwise return kNotFound.
1819template<typename Shape, typename Key>
1820int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
1821 uint32_t capacity = Capacity();
1822 uint32_t entry = FirstProbe(Shape::Hash(key), capacity);
1823 uint32_t count = 1;
1824 // EnsureCapacity will guarantee the hash table is never full.
1825 while (true) {
1826 Object* element = KeyAt(entry);
1827 if (element == isolate->heap()->undefined_value()) break; // Empty entry.
1828 if (element != isolate->heap()->null_value() &&
1829 Shape::IsMatch(key, element)) return entry;
1830 entry = NextProbe(entry, count++, capacity);
1831 }
1832 return kNotFound;
1833}
1834
1835
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001836bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001837 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001838 if (!max_index_object->IsSmi()) return false;
1839 return 0 !=
1840 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1841}
1842
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001843uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001844 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001845 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001846 if (!max_index_object->IsSmi()) return 0;
1847 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1848 return value >> kRequiresSlowElementsTagSize;
1849}
1850
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001851void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001852 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001853}
1854
1855
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001856// ------------------------------------
1857// Cast operations
1858
1859
1860CAST_ACCESSOR(FixedArray)
1861CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001862CAST_ACCESSOR(DeoptimizationInputData)
1863CAST_ACCESSOR(DeoptimizationOutputData)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001864CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00001865CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00001866CAST_ACCESSOR(NormalizedMapCache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00001867CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001868CAST_ACCESSOR(CodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00001869CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001870CAST_ACCESSOR(String)
1871CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00001872CAST_ACCESSOR(SeqAsciiString)
1873CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001874CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001875CAST_ACCESSOR(ExternalString)
1876CAST_ACCESSOR(ExternalAsciiString)
1877CAST_ACCESSOR(ExternalTwoByteString)
1878CAST_ACCESSOR(JSObject)
1879CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001880CAST_ACCESSOR(HeapObject)
1881CAST_ACCESSOR(HeapNumber)
1882CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001883CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001884CAST_ACCESSOR(SharedFunctionInfo)
1885CAST_ACCESSOR(Map)
1886CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001887CAST_ACCESSOR(GlobalObject)
1888CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001889CAST_ACCESSOR(JSGlobalObject)
1890CAST_ACCESSOR(JSBuiltinsObject)
1891CAST_ACCESSOR(Code)
1892CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00001893CAST_ACCESSOR(JSRegExp)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001894CAST_ACCESSOR(Proxy)
1895CAST_ACCESSOR(ByteArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00001896CAST_ACCESSOR(ExternalArray)
1897CAST_ACCESSOR(ExternalByteArray)
1898CAST_ACCESSOR(ExternalUnsignedByteArray)
1899CAST_ACCESSOR(ExternalShortArray)
1900CAST_ACCESSOR(ExternalUnsignedShortArray)
1901CAST_ACCESSOR(ExternalIntArray)
1902CAST_ACCESSOR(ExternalUnsignedIntArray)
1903CAST_ACCESSOR(ExternalFloatArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001904CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001905CAST_ACCESSOR(Struct)
1906
1907
1908#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
1909 STRUCT_LIST(MAKE_STRUCT_CAST)
1910#undef MAKE_STRUCT_CAST
1911
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001912
1913template <typename Shape, typename Key>
1914HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001915 ASSERT(obj->IsHashTable());
1916 return reinterpret_cast<HashTable*>(obj);
1917}
1918
1919
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001920SMI_ACCESSORS(FixedArray, length, kLengthOffset)
1921SMI_ACCESSORS(ByteArray, length, kLengthOffset)
1922
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001923INT_ACCESSORS(ExternalArray, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001924
1925
ager@chromium.orgac091b72010-05-05 07:34:42 +00001926SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001927
1928
1929uint32_t String::hash_field() {
1930 return READ_UINT32_FIELD(this, kHashFieldOffset);
1931}
1932
1933
1934void String::set_hash_field(uint32_t value) {
1935 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001936#if V8_HOST_ARCH_64_BIT
1937 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
1938#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001939}
1940
1941
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001942bool String::Equals(String* other) {
1943 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001944 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
1945 return false;
1946 }
1947 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001948}
1949
1950
lrn@chromium.org303ada72010-10-27 09:33:13 +00001951MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001952 if (!StringShape(this).IsCons()) return this;
1953 ConsString* cons = ConsString::cast(this);
1954 if (cons->second()->length() == 0) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001955 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001956}
1957
1958
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001959String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00001960 MaybeObject* flat = TryFlatten(pretenure);
1961 Object* successfully_flattened;
1962 if (flat->ToObject(&successfully_flattened)) {
1963 return String::cast(successfully_flattened);
1964 }
1965 return this;
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001966}
1967
1968
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001969uint16_t String::Get(int index) {
1970 ASSERT(index >= 0 && index < length());
1971 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001972 case kSeqStringTag | kAsciiStringTag:
1973 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
1974 case kSeqStringTag | kTwoByteStringTag:
1975 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
1976 case kConsStringTag | kAsciiStringTag:
1977 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001978 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00001979 case kExternalStringTag | kAsciiStringTag:
1980 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
1981 case kExternalStringTag | kTwoByteStringTag:
1982 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001983 default:
1984 break;
1985 }
1986
1987 UNREACHABLE();
1988 return 0;
1989}
1990
1991
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001992void String::Set(int index, uint16_t value) {
1993 ASSERT(index >= 0 && index < length());
1994 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001995
ager@chromium.org5ec48922009-05-05 07:25:34 +00001996 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00001997 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
1998 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001999}
2000
2001
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002002bool String::IsFlat() {
2003 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002004 case kConsStringTag: {
2005 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00002006 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00002007 return second->length() == 0;
2008 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00002009 default:
2010 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002011 }
2012}
2013
2014
ager@chromium.org7c537e22008-10-16 08:43:32 +00002015uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002016 ASSERT(index >= 0 && index < length());
2017 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2018}
2019
2020
ager@chromium.org7c537e22008-10-16 08:43:32 +00002021void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002022 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2023 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2024 static_cast<byte>(value));
2025}
2026
2027
ager@chromium.org7c537e22008-10-16 08:43:32 +00002028Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002029 return FIELD_ADDR(this, kHeaderSize);
2030}
2031
2032
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002033char* SeqAsciiString::GetChars() {
2034 return reinterpret_cast<char*>(GetCharsAddress());
2035}
2036
2037
ager@chromium.org7c537e22008-10-16 08:43:32 +00002038Address SeqTwoByteString::GetCharsAddress() {
2039 return FIELD_ADDR(this, kHeaderSize);
2040}
2041
2042
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002043uc16* SeqTwoByteString::GetChars() {
2044 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2045}
2046
2047
ager@chromium.org7c537e22008-10-16 08:43:32 +00002048uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002049 ASSERT(index >= 0 && index < length());
2050 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2051}
2052
2053
ager@chromium.org7c537e22008-10-16 08:43:32 +00002054void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002055 ASSERT(index >= 0 && index < length());
2056 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2057}
2058
2059
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002060int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002061 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002062}
2063
2064
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002065int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002066 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002067}
2068
2069
ager@chromium.org870a0b62008-11-04 11:43:05 +00002070String* ConsString::first() {
2071 return String::cast(READ_FIELD(this, kFirstOffset));
2072}
2073
2074
2075Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002076 return READ_FIELD(this, kFirstOffset);
2077}
2078
2079
ager@chromium.org870a0b62008-11-04 11:43:05 +00002080void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002081 WRITE_FIELD(this, kFirstOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002082 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002083}
2084
2085
ager@chromium.org870a0b62008-11-04 11:43:05 +00002086String* ConsString::second() {
2087 return String::cast(READ_FIELD(this, kSecondOffset));
2088}
2089
2090
2091Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002092 return READ_FIELD(this, kSecondOffset);
2093}
2094
2095
ager@chromium.org870a0b62008-11-04 11:43:05 +00002096void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002097 WRITE_FIELD(this, kSecondOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002098 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002099}
2100
2101
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002102ExternalAsciiString::Resource* ExternalAsciiString::resource() {
2103 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2104}
2105
2106
2107void ExternalAsciiString::set_resource(
2108 ExternalAsciiString::Resource* resource) {
2109 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2110}
2111
2112
2113ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
2114 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2115}
2116
2117
2118void ExternalTwoByteString::set_resource(
2119 ExternalTwoByteString::Resource* resource) {
2120 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2121}
2122
2123
ager@chromium.orgac091b72010-05-05 07:34:42 +00002124void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002125 set_finger_index(kEntriesIndex);
2126 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002127}
2128
2129
2130void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002131 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002132 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002133 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002134 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002135 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002136 MakeZeroSize();
2137}
2138
2139
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002140int JSFunctionResultCache::size() {
2141 return Smi::cast(get(kCacheSizeIndex))->value();
2142}
2143
2144
2145void JSFunctionResultCache::set_size(int size) {
2146 set(kCacheSizeIndex, Smi::FromInt(size));
2147}
2148
2149
2150int JSFunctionResultCache::finger_index() {
2151 return Smi::cast(get(kFingerIndex))->value();
2152}
2153
2154
2155void JSFunctionResultCache::set_finger_index(int finger_index) {
2156 set(kFingerIndex, Smi::FromInt(finger_index));
2157}
2158
2159
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002160byte ByteArray::get(int index) {
2161 ASSERT(index >= 0 && index < this->length());
2162 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2163}
2164
2165
2166void ByteArray::set(int index, byte value) {
2167 ASSERT(index >= 0 && index < this->length());
2168 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2169}
2170
2171
2172int ByteArray::get_int(int index) {
2173 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2174 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2175}
2176
2177
2178ByteArray* ByteArray::FromDataStartAddress(Address address) {
2179 ASSERT_TAG_ALIGNED(address);
2180 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2181}
2182
2183
2184Address ByteArray::GetDataStartAddress() {
2185 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2186}
2187
2188
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002189uint8_t* ExternalPixelArray::external_pixel_pointer() {
2190 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002191}
2192
2193
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002194uint8_t ExternalPixelArray::get(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002195 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002196 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002197 return ptr[index];
2198}
2199
2200
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002201void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002202 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002203 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002204 ptr[index] = value;
2205}
2206
2207
ager@chromium.org3811b432009-10-28 14:53:37 +00002208void* ExternalArray::external_pointer() {
2209 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2210 return reinterpret_cast<void*>(ptr);
2211}
2212
2213
2214void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2215 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2216 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2217}
2218
2219
2220int8_t ExternalByteArray::get(int index) {
2221 ASSERT((index >= 0) && (index < this->length()));
2222 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2223 return ptr[index];
2224}
2225
2226
2227void ExternalByteArray::set(int index, int8_t value) {
2228 ASSERT((index >= 0) && (index < this->length()));
2229 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2230 ptr[index] = value;
2231}
2232
2233
2234uint8_t ExternalUnsignedByteArray::get(int index) {
2235 ASSERT((index >= 0) && (index < this->length()));
2236 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2237 return ptr[index];
2238}
2239
2240
2241void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2242 ASSERT((index >= 0) && (index < this->length()));
2243 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2244 ptr[index] = value;
2245}
2246
2247
2248int16_t ExternalShortArray::get(int index) {
2249 ASSERT((index >= 0) && (index < this->length()));
2250 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2251 return ptr[index];
2252}
2253
2254
2255void ExternalShortArray::set(int index, int16_t value) {
2256 ASSERT((index >= 0) && (index < this->length()));
2257 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2258 ptr[index] = value;
2259}
2260
2261
2262uint16_t ExternalUnsignedShortArray::get(int index) {
2263 ASSERT((index >= 0) && (index < this->length()));
2264 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2265 return ptr[index];
2266}
2267
2268
2269void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2270 ASSERT((index >= 0) && (index < this->length()));
2271 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2272 ptr[index] = value;
2273}
2274
2275
2276int32_t ExternalIntArray::get(int index) {
2277 ASSERT((index >= 0) && (index < this->length()));
2278 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2279 return ptr[index];
2280}
2281
2282
2283void ExternalIntArray::set(int index, int32_t value) {
2284 ASSERT((index >= 0) && (index < this->length()));
2285 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2286 ptr[index] = value;
2287}
2288
2289
2290uint32_t ExternalUnsignedIntArray::get(int index) {
2291 ASSERT((index >= 0) && (index < this->length()));
2292 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2293 return ptr[index];
2294}
2295
2296
2297void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2298 ASSERT((index >= 0) && (index < this->length()));
2299 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2300 ptr[index] = value;
2301}
2302
2303
2304float ExternalFloatArray::get(int index) {
2305 ASSERT((index >= 0) && (index < this->length()));
2306 float* ptr = static_cast<float*>(external_pointer());
2307 return ptr[index];
2308}
2309
2310
2311void ExternalFloatArray::set(int index, float value) {
2312 ASSERT((index >= 0) && (index < this->length()));
2313 float* ptr = static_cast<float*>(external_pointer());
2314 ptr[index] = value;
2315}
2316
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002317
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002318int Map::visitor_id() {
2319 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2320}
2321
2322
2323void Map::set_visitor_id(int id) {
2324 ASSERT(0 <= id && id < 256);
2325 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2326}
2327
ager@chromium.org3811b432009-10-28 14:53:37 +00002328
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002329int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002330 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2331}
2332
2333
2334int Map::inobject_properties() {
2335 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002336}
2337
2338
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002339int Map::pre_allocated_property_fields() {
2340 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2341}
2342
2343
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002344int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002345 int instance_size = map->instance_size();
2346 if (instance_size != kVariableSizeSentinel) return instance_size;
2347 // We can ignore the "symbol" bit becase it is only set for symbols
2348 // and implies a string type.
2349 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002350 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002351 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002352 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002353 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002354 if (instance_type == ASCII_STRING_TYPE) {
2355 return SeqAsciiString::SizeFor(
2356 reinterpret_cast<SeqAsciiString*>(this)->length());
2357 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002358 if (instance_type == BYTE_ARRAY_TYPE) {
2359 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2360 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002361 if (instance_type == STRING_TYPE) {
2362 return SeqTwoByteString::SizeFor(
2363 reinterpret_cast<SeqTwoByteString*>(this)->length());
2364 }
2365 ASSERT(instance_type == CODE_TYPE);
2366 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002367}
2368
2369
2370void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002371 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002372 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002373 ASSERT(0 <= value && value < 256);
2374 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2375}
2376
2377
ager@chromium.org7c537e22008-10-16 08:43:32 +00002378void Map::set_inobject_properties(int value) {
2379 ASSERT(0 <= value && value < 256);
2380 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2381}
2382
2383
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002384void Map::set_pre_allocated_property_fields(int value) {
2385 ASSERT(0 <= value && value < 256);
2386 WRITE_BYTE_FIELD(this,
2387 kPreAllocatedPropertyFieldsOffset,
2388 static_cast<byte>(value));
2389}
2390
2391
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002392InstanceType Map::instance_type() {
2393 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2394}
2395
2396
2397void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002398 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2399}
2400
2401
2402int Map::unused_property_fields() {
2403 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2404}
2405
2406
2407void Map::set_unused_property_fields(int value) {
2408 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2409}
2410
2411
2412byte Map::bit_field() {
2413 return READ_BYTE_FIELD(this, kBitFieldOffset);
2414}
2415
2416
2417void Map::set_bit_field(byte value) {
2418 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2419}
2420
2421
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002422byte Map::bit_field2() {
2423 return READ_BYTE_FIELD(this, kBitField2Offset);
2424}
2425
2426
2427void Map::set_bit_field2(byte value) {
2428 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2429}
2430
2431
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002432void Map::set_non_instance_prototype(bool value) {
2433 if (value) {
2434 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2435 } else {
2436 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2437 }
2438}
2439
2440
2441bool Map::has_non_instance_prototype() {
2442 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2443}
2444
2445
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002446void Map::set_function_with_prototype(bool value) {
2447 if (value) {
2448 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2449 } else {
2450 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2451 }
2452}
2453
2454
2455bool Map::function_with_prototype() {
2456 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2457}
2458
2459
ager@chromium.org870a0b62008-11-04 11:43:05 +00002460void Map::set_is_access_check_needed(bool access_check_needed) {
2461 if (access_check_needed) {
2462 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2463 } else {
2464 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2465 }
2466}
2467
2468
2469bool Map::is_access_check_needed() {
2470 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2471}
2472
2473
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002474void Map::set_is_extensible(bool value) {
2475 if (value) {
2476 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2477 } else {
2478 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2479 }
2480}
2481
2482bool Map::is_extensible() {
2483 return ((1 << kIsExtensible) & bit_field2()) != 0;
2484}
2485
2486
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002487void Map::set_attached_to_shared_function_info(bool value) {
2488 if (value) {
2489 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2490 } else {
2491 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2492 }
2493}
2494
2495bool Map::attached_to_shared_function_info() {
2496 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2497}
2498
2499
2500void Map::set_is_shared(bool value) {
2501 if (value) {
2502 set_bit_field2(bit_field2() | (1 << kIsShared));
2503 } else {
2504 set_bit_field2(bit_field2() & ~(1 << kIsShared));
2505 }
2506}
2507
2508bool Map::is_shared() {
2509 return ((1 << kIsShared) & bit_field2()) != 0;
2510}
2511
2512
2513JSFunction* Map::unchecked_constructor() {
2514 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2515}
2516
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002517
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002518Code::Flags Code::flags() {
2519 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2520}
2521
2522
2523void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002524 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002525 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002526 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2527 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002528 ExtractArgumentsCountFromFlags(flags) >= 0);
2529 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2530}
2531
2532
2533Code::Kind Code::kind() {
2534 return ExtractKindFromFlags(flags());
2535}
2536
2537
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002538InLoopFlag Code::ic_in_loop() {
2539 return ExtractICInLoopFromFlags(flags());
2540}
2541
2542
kasper.lund7276f142008-07-30 08:49:36 +00002543InlineCacheState Code::ic_state() {
2544 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002545 // Only allow uninitialized or debugger states for non-IC code
2546 // objects. This is used in the debugger to determine whether or not
2547 // a call to code object has been replaced with a debug break call.
2548 ASSERT(is_inline_cache_stub() ||
2549 result == UNINITIALIZED ||
2550 result == DEBUG_BREAK ||
2551 result == DEBUG_PREPARE_STEP_IN);
2552 return result;
2553}
2554
2555
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002556Code::ExtraICState Code::extra_ic_state() {
2557 ASSERT(is_inline_cache_stub());
2558 return ExtractExtraICStateFromFlags(flags());
2559}
2560
2561
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002562PropertyType Code::type() {
kasper.lund7276f142008-07-30 08:49:36 +00002563 ASSERT(ic_state() == MONOMORPHIC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002564 return ExtractTypeFromFlags(flags());
2565}
2566
2567
2568int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002569 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002570 return ExtractArgumentsCountFromFlags(flags());
2571}
2572
2573
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002574int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002575 ASSERT(kind() == STUB ||
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002576 kind() == TYPE_RECORDING_BINARY_OP_IC ||
2577 kind() == COMPARE_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002578 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002579}
2580
2581
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002582void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002583 ASSERT(kind() == STUB ||
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002584 kind() == TYPE_RECORDING_BINARY_OP_IC ||
2585 kind() == COMPARE_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002586 ASSERT(0 <= major && major < 256);
2587 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002588}
2589
2590
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002591bool Code::optimizable() {
2592 ASSERT(kind() == FUNCTION);
2593 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2594}
2595
2596
2597void Code::set_optimizable(bool value) {
2598 ASSERT(kind() == FUNCTION);
2599 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2600}
2601
2602
2603bool Code::has_deoptimization_support() {
2604 ASSERT(kind() == FUNCTION);
2605 return READ_BYTE_FIELD(this, kHasDeoptimizationSupportOffset) == 1;
2606}
2607
2608
2609void Code::set_has_deoptimization_support(bool value) {
2610 ASSERT(kind() == FUNCTION);
2611 WRITE_BYTE_FIELD(this, kHasDeoptimizationSupportOffset, value ? 1 : 0);
2612}
2613
2614
2615int Code::allow_osr_at_loop_nesting_level() {
2616 ASSERT(kind() == FUNCTION);
2617 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
2618}
2619
2620
2621void Code::set_allow_osr_at_loop_nesting_level(int level) {
2622 ASSERT(kind() == FUNCTION);
2623 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
2624 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
2625}
2626
2627
2628unsigned Code::stack_slots() {
2629 ASSERT(kind() == OPTIMIZED_FUNCTION);
2630 return READ_UINT32_FIELD(this, kStackSlotsOffset);
2631}
2632
2633
2634void Code::set_stack_slots(unsigned slots) {
2635 ASSERT(kind() == OPTIMIZED_FUNCTION);
2636 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
2637}
2638
2639
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002640unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002641 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002642 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002643}
2644
2645
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002646void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002647 ASSERT(kind() == OPTIMIZED_FUNCTION);
2648 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002649 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002650}
2651
2652
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002653unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002654 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002655 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002656}
2657
2658
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002659void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002660 ASSERT(kind() == FUNCTION);
2661 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002662 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002663}
2664
2665
2666CheckType Code::check_type() {
2667 ASSERT(is_call_stub() || is_keyed_call_stub());
2668 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
2669 return static_cast<CheckType>(type);
2670}
2671
2672
2673void Code::set_check_type(CheckType value) {
2674 ASSERT(is_call_stub() || is_keyed_call_stub());
2675 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
2676}
2677
2678
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002679ExternalArrayType Code::external_array_type() {
2680 ASSERT(is_external_array_load_stub() || is_external_array_store_stub());
2681 byte type = READ_BYTE_FIELD(this, kExternalArrayTypeOffset);
2682 return static_cast<ExternalArrayType>(type);
2683}
2684
2685
2686void Code::set_external_array_type(ExternalArrayType value) {
2687 ASSERT(is_external_array_load_stub() || is_external_array_store_stub());
2688 WRITE_BYTE_FIELD(this, kExternalArrayTypeOffset, value);
2689}
2690
2691
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002692byte Code::type_recording_binary_op_type() {
2693 ASSERT(is_type_recording_binary_op_stub());
2694 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
2695}
2696
2697
2698void Code::set_type_recording_binary_op_type(byte value) {
2699 ASSERT(is_type_recording_binary_op_stub());
2700 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
2701}
2702
2703
2704byte Code::type_recording_binary_op_result_type() {
2705 ASSERT(is_type_recording_binary_op_stub());
2706 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
2707}
2708
2709
2710void Code::set_type_recording_binary_op_result_type(byte value) {
2711 ASSERT(is_type_recording_binary_op_stub());
2712 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
2713}
2714
2715
2716byte Code::compare_state() {
2717 ASSERT(is_compare_ic_stub());
2718 return READ_BYTE_FIELD(this, kCompareStateOffset);
2719}
2720
2721
2722void Code::set_compare_state(byte value) {
2723 ASSERT(is_compare_ic_stub());
2724 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
2725}
2726
2727
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002728bool Code::is_inline_cache_stub() {
2729 Kind kind = this->kind();
2730 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2731}
2732
2733
2734Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002735 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002736 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002737 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002738 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002739 int argc,
2740 InlineCacheHolderFlag holder) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002741 // Extra IC state is only allowed for monomorphic call IC stubs
2742 // or for store IC stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002743 ASSERT(extra_ic_state == kNoExtraICState ||
2744 (kind == CALL_IC && (ic_state == MONOMORPHIC ||
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002745 ic_state == MONOMORPHIC_PROTOTYPE_FAILURE)) ||
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00002746 (kind == STORE_IC) ||
2747 (kind == KEYED_STORE_IC));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002748 // Compute the bit mask.
2749 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002750 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002751 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002752 bits |= type << kFlagsTypeShift;
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002753 bits |= extra_ic_state << kFlagsExtraICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002754 bits |= argc << kFlagsArgumentsCountShift;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002755 if (holder == PROTOTYPE_MAP) bits |= kFlagsCacheInPrototypeMapMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002756 // Cast to flags and validate result before returning it.
2757 Flags result = static_cast<Flags>(bits);
2758 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002759 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002760 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002761 ASSERT(ExtractTypeFromFlags(result) == type);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002762 ASSERT(ExtractExtraICStateFromFlags(result) == extra_ic_state);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002763 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2764 return result;
2765}
2766
2767
2768Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2769 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002770 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002771 InlineCacheHolderFlag holder,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002772 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002773 int argc) {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002774 return ComputeFlags(
2775 kind, in_loop, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002776}
2777
2778
2779Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2780 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2781 return static_cast<Kind>(bits);
2782}
2783
2784
kasper.lund7276f142008-07-30 08:49:36 +00002785InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2786 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002787 return static_cast<InlineCacheState>(bits);
2788}
2789
2790
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002791Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
2792 int bits = (flags & kFlagsExtraICStateMask) >> kFlagsExtraICStateShift;
2793 return static_cast<ExtraICState>(bits);
2794}
2795
2796
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002797InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2798 int bits = (flags & kFlagsICInLoopMask);
2799 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2800}
2801
2802
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002803PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2804 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2805 return static_cast<PropertyType>(bits);
2806}
2807
2808
2809int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2810 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2811}
2812
2813
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002814InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
2815 int bits = (flags & kFlagsCacheInPrototypeMapMask);
2816 return bits != 0 ? PROTOTYPE_MAP : OWN_MAP;
2817}
2818
2819
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002820Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2821 int bits = flags & ~kFlagsTypeMask;
2822 return static_cast<Flags>(bits);
2823}
2824
2825
ager@chromium.org8bb60582008-12-11 12:02:20 +00002826Code* Code::GetCodeFromTargetAddress(Address address) {
2827 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2828 // GetCodeFromTargetAddress might be called when marking objects during mark
2829 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2830 // Code::cast. Code::cast does not work when the object's map is
2831 // marked.
2832 Code* result = reinterpret_cast<Code*>(code);
2833 return result;
2834}
2835
2836
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002837Isolate* Map::isolate() {
2838 return heap()->isolate();
2839}
2840
2841
2842Heap* Map::heap() {
2843 // NOTE: address() helper is not used to save one instruction.
2844 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
2845 ASSERT(heap != NULL);
2846 ASSERT(heap->isolate() == Isolate::Current());
2847 return heap;
2848}
2849
2850
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002851Heap* Code::heap() {
2852 // NOTE: address() helper is not used to save one instruction.
2853 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
2854 ASSERT(heap != NULL);
2855 ASSERT(heap->isolate() == Isolate::Current());
2856 return heap;
2857}
2858
2859
2860Isolate* Code::isolate() {
2861 return heap()->isolate();
2862}
2863
2864
2865Heap* JSGlobalPropertyCell::heap() {
2866 // NOTE: address() helper is not used to save one instruction.
2867 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
2868 ASSERT(heap != NULL);
2869 ASSERT(heap->isolate() == Isolate::Current());
2870 return heap;
2871}
2872
2873
2874Isolate* JSGlobalPropertyCell::isolate() {
2875 return heap()->isolate();
2876}
2877
2878
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002879Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
2880 return HeapObject::
2881 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
2882}
2883
2884
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002885Object* Map::prototype() {
2886 return READ_FIELD(this, kPrototypeOffset);
2887}
2888
2889
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002890void Map::set_prototype(Object* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002891 ASSERT(value->IsNull() || value->IsJSObject());
2892 WRITE_FIELD(this, kPrototypeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002893 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002894}
2895
2896
lrn@chromium.org303ada72010-10-27 09:33:13 +00002897MaybeObject* Map::GetFastElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002898 if (has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00002899 Object* obj;
2900 { MaybeObject* maybe_obj = CopyDropTransitions();
2901 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2902 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002903 Map* new_map = Map::cast(obj);
2904 new_map->set_has_fast_elements(true);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002905 isolate()->counters()->map_slow_to_fast_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002906 return new_map;
2907}
2908
2909
lrn@chromium.org303ada72010-10-27 09:33:13 +00002910MaybeObject* Map::GetSlowElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002911 if (!has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00002912 Object* obj;
2913 { MaybeObject* maybe_obj = CopyDropTransitions();
2914 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2915 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002916 Map* new_map = Map::cast(obj);
2917 new_map->set_has_fast_elements(false);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002918 isolate()->counters()->map_fast_to_slow_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002919 return new_map;
2920}
2921
2922
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002923ACCESSORS(Map, instance_descriptors, DescriptorArray,
2924 kInstanceDescriptorsOffset)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002925ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002926ACCESSORS(Map, constructor, Object, kConstructorOffset)
2927
2928ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
2929ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002930ACCESSORS_GCSAFE(JSFunction, next_function_link, Object,
2931 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002932
2933ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
2934ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002935ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002936
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002937ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002938
2939ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
2940ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
2941ACCESSORS(AccessorInfo, data, Object, kDataOffset)
2942ACCESSORS(AccessorInfo, name, Object, kNameOffset)
2943ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
2944
2945ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
2946ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
2947ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
2948
2949ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
2950ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
2951ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
2952ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
2953ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
2954ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
2955
2956ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
2957ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
2958
2959ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
2960ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
2961
2962ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
2963ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002964ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
2965 kPropertyAccessorsOffset)
2966ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
2967 kPrototypeTemplateOffset)
2968ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
2969ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
2970 kNamedPropertyHandlerOffset)
2971ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
2972 kIndexedPropertyHandlerOffset)
2973ACCESSORS(FunctionTemplateInfo, instance_template, Object,
2974 kInstanceTemplateOffset)
2975ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
2976ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002977ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
2978 kInstanceCallHandlerOffset)
2979ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
2980 kAccessCheckInfoOffset)
2981ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
2982
2983ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00002984ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
2985 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002986
2987ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
2988ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
2989
2990ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
2991
2992ACCESSORS(Script, source, Object, kSourceOffset)
2993ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002994ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002995ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
2996ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002997ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00002998ACCESSORS(Script, context_data, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002999ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
3000ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003001ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003002ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003003ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003004ACCESSORS(Script, eval_from_instructions_offset, Smi,
3005 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003006
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003007#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003008ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3009ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3010ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3011ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3012
3013ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3014ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3015ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3016ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003017#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003018
3019ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003020ACCESSORS_GCSAFE(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3021ACCESSORS_GCSAFE(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003022ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3023 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003024ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003025ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3026ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003027ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003028ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3029 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003030
3031BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3032 kHiddenPrototypeBit)
3033BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3034BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3035 kNeedsAccessCheckBit)
3036BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3037 kIsExpressionBit)
3038BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3039 kIsTopLevelBit)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003040BOOL_GETTER(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003041 has_only_simple_this_property_assignments,
3042 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003043BOOL_ACCESSORS(SharedFunctionInfo,
3044 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003045 allows_lazy_compilation,
3046 kAllowLazyCompilation)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003047
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003048
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003049#if V8_HOST_ARCH_32_BIT
3050SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3051SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003052 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003053SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003054 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003055SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3056SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003057 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003058SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3059SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003060 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003061SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003062 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003063SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003064 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003065SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003066#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003067
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003068#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003069 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003070 int holder::name() { \
3071 int value = READ_INT_FIELD(this, offset); \
3072 ASSERT(kHeapObjectTag == 1); \
3073 ASSERT((value & kHeapObjectTag) == 0); \
3074 return value >> 1; \
3075 } \
3076 void holder::set_##name(int value) { \
3077 ASSERT(kHeapObjectTag == 1); \
3078 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3079 (value & 0xC0000000) == 0x000000000); \
3080 WRITE_INT_FIELD(this, \
3081 offset, \
3082 (value << 1) & ~kHeapObjectTag); \
3083 }
3084
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003085#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3086 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003087 INT_ACCESSORS(holder, name, offset)
3088
3089
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003090PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003091PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3092 formal_parameter_count,
3093 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003094
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003095PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3096 expected_nof_properties,
3097 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003098PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3099
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003100PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3101PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3102 start_position_and_type,
3103 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003104
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003105PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3106 function_token_position,
3107 kFunctionTokenPositionOffset)
3108PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3109 compiler_hints,
3110 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003111
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003112PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3113 this_property_assignments_count,
3114 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003115PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003116#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003117
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003118
3119int SharedFunctionInfo::construction_count() {
3120 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3121}
3122
3123
3124void SharedFunctionInfo::set_construction_count(int value) {
3125 ASSERT(0 <= value && value < 256);
3126 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3127}
3128
3129
3130bool SharedFunctionInfo::live_objects_may_exist() {
3131 return (compiler_hints() & (1 << kLiveObjectsMayExist)) != 0;
3132}
3133
3134
3135void SharedFunctionInfo::set_live_objects_may_exist(bool value) {
3136 if (value) {
3137 set_compiler_hints(compiler_hints() | (1 << kLiveObjectsMayExist));
3138 } else {
3139 set_compiler_hints(compiler_hints() & ~(1 << kLiveObjectsMayExist));
3140 }
3141}
3142
3143
3144bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003145 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003146}
3147
3148
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003149bool SharedFunctionInfo::optimization_disabled() {
3150 return BooleanBit::get(compiler_hints(), kOptimizationDisabled);
3151}
3152
3153
3154void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3155 set_compiler_hints(BooleanBit::set(compiler_hints(),
3156 kOptimizationDisabled,
3157 disable));
3158 // If disabling optimizations we reflect that in the code object so
3159 // it will not be counted as optimizable code.
3160 if ((code()->kind() == Code::FUNCTION) && disable) {
3161 code()->set_optimizable(false);
3162 }
3163}
3164
3165
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003166bool SharedFunctionInfo::strict_mode() {
3167 return BooleanBit::get(compiler_hints(), kStrictModeFunction);
3168}
3169
3170
3171void SharedFunctionInfo::set_strict_mode(bool value) {
3172 set_compiler_hints(BooleanBit::set(compiler_hints(),
3173 kStrictModeFunction,
3174 value));
3175}
3176
3177
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003178ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3179ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3180
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003181bool Script::HasValidSource() {
3182 Object* src = this->source();
3183 if (!src->IsString()) return true;
3184 String* src_str = String::cast(src);
3185 if (!StringShape(src_str).IsExternal()) return true;
3186 if (src_str->IsAsciiRepresentation()) {
3187 return ExternalAsciiString::cast(src)->resource() != NULL;
3188 } else if (src_str->IsTwoByteRepresentation()) {
3189 return ExternalTwoByteString::cast(src)->resource() != NULL;
3190 }
3191 return true;
3192}
3193
3194
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003195void SharedFunctionInfo::DontAdaptArguments() {
3196 ASSERT(code()->kind() == Code::BUILTIN);
3197 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3198}
3199
3200
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003201int SharedFunctionInfo::start_position() {
3202 return start_position_and_type() >> kStartPositionShift;
3203}
3204
3205
3206void SharedFunctionInfo::set_start_position(int start_position) {
3207 set_start_position_and_type((start_position << kStartPositionShift)
3208 | (start_position_and_type() & ~kStartPositionMask));
3209}
3210
3211
3212Code* SharedFunctionInfo::code() {
3213 return Code::cast(READ_FIELD(this, kCodeOffset));
3214}
3215
3216
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003217Code* SharedFunctionInfo::unchecked_code() {
3218 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3219}
3220
3221
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003222void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003223 WRITE_FIELD(this, kCodeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003224 ASSERT(!Isolate::Current()->heap()->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003225}
3226
3227
ager@chromium.orgb5737492010-07-15 09:29:43 +00003228SerializedScopeInfo* SharedFunctionInfo::scope_info() {
3229 return reinterpret_cast<SerializedScopeInfo*>(
3230 READ_FIELD(this, kScopeInfoOffset));
3231}
3232
3233
3234void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
3235 WriteBarrierMode mode) {
3236 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003237 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kScopeInfoOffset, mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003238}
3239
3240
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003241Smi* SharedFunctionInfo::deopt_counter() {
3242 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3243}
3244
3245
3246void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3247 WRITE_FIELD(this, kDeoptCounterOffset, value);
3248}
3249
3250
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003251bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003252 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003253 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003254}
3255
3256
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003257bool SharedFunctionInfo::IsApiFunction() {
3258 return function_data()->IsFunctionTemplateInfo();
3259}
3260
3261
3262FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3263 ASSERT(IsApiFunction());
3264 return FunctionTemplateInfo::cast(function_data());
3265}
3266
3267
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003268bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003269 return function_data()->IsSmi();
3270}
3271
3272
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003273BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3274 ASSERT(HasBuiltinFunctionId());
3275 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003276}
3277
3278
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003279int SharedFunctionInfo::code_age() {
3280 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3281}
3282
3283
3284void SharedFunctionInfo::set_code_age(int code_age) {
3285 set_compiler_hints(compiler_hints() |
3286 ((code_age & kCodeAgeMask) << kCodeAgeShift));
3287}
3288
3289
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003290bool SharedFunctionInfo::has_deoptimization_support() {
3291 Code* code = this->code();
3292 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3293}
3294
3295
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003296bool JSFunction::IsBuiltin() {
3297 return context()->global()->IsJSBuiltinsObject();
3298}
3299
3300
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003301bool JSFunction::NeedsArgumentsAdaption() {
3302 return shared()->formal_parameter_count() !=
3303 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3304}
3305
3306
3307bool JSFunction::IsOptimized() {
3308 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3309}
3310
3311
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003312bool JSFunction::IsOptimizable() {
3313 return code()->kind() == Code::FUNCTION && code()->optimizable();
3314}
3315
3316
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003317bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003318 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003319}
3320
3321
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003322Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003323 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003324}
3325
3326
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003327Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003328 return reinterpret_cast<Code*>(
3329 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003330}
3331
3332
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003333void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00003334 // Skip the write barrier because code is never in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003335 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003336 Address entry = value->entry();
3337 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003338}
3339
3340
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003341void JSFunction::ReplaceCode(Code* code) {
3342 bool was_optimized = IsOptimized();
3343 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3344
3345 set_code(code);
3346
3347 // Add/remove the function from the list of optimized functions for this
3348 // context based on the state change.
3349 if (!was_optimized && is_optimized) {
3350 context()->global_context()->AddOptimizedFunction(this);
3351 }
3352 if (was_optimized && !is_optimized) {
3353 context()->global_context()->RemoveOptimizedFunction(this);
3354 }
3355}
3356
3357
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003358Context* JSFunction::context() {
3359 return Context::cast(READ_FIELD(this, kContextOffset));
3360}
3361
3362
3363Object* JSFunction::unchecked_context() {
3364 return READ_FIELD(this, kContextOffset);
3365}
3366
3367
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003368SharedFunctionInfo* JSFunction::unchecked_shared() {
3369 return reinterpret_cast<SharedFunctionInfo*>(
3370 READ_FIELD(this, kSharedFunctionInfoOffset));
3371}
3372
3373
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003374void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003375 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003376 WRITE_FIELD(this, kContextOffset, value);
3377 WRITE_BARRIER(this, kContextOffset);
3378}
3379
3380ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3381 kPrototypeOrInitialMapOffset)
3382
3383
3384Map* JSFunction::initial_map() {
3385 return Map::cast(prototype_or_initial_map());
3386}
3387
3388
3389void JSFunction::set_initial_map(Map* value) {
3390 set_prototype_or_initial_map(value);
3391}
3392
3393
3394bool JSFunction::has_initial_map() {
3395 return prototype_or_initial_map()->IsMap();
3396}
3397
3398
3399bool JSFunction::has_instance_prototype() {
3400 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3401}
3402
3403
3404bool JSFunction::has_prototype() {
3405 return map()->has_non_instance_prototype() || has_instance_prototype();
3406}
3407
3408
3409Object* JSFunction::instance_prototype() {
3410 ASSERT(has_instance_prototype());
3411 if (has_initial_map()) return initial_map()->prototype();
3412 // When there is no initial map and the prototype is a JSObject, the
3413 // initial map field is used for the prototype field.
3414 return prototype_or_initial_map();
3415}
3416
3417
3418Object* JSFunction::prototype() {
3419 ASSERT(has_prototype());
3420 // If the function's prototype property has been set to a non-JSObject
3421 // value, that value is stored in the constructor field of the map.
3422 if (map()->has_non_instance_prototype()) return map()->constructor();
3423 return instance_prototype();
3424}
3425
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003426bool JSFunction::should_have_prototype() {
3427 return map()->function_with_prototype();
3428}
3429
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003430
3431bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003432 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003433}
3434
3435
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003436int JSFunction::NumberOfLiterals() {
3437 return literals()->length();
3438}
3439
3440
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003441Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003442 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003443 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003444}
3445
3446
3447void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3448 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003449 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003450 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
3451 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
3452}
3453
3454
3455Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003456 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003457 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3458}
3459
3460
3461void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3462 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003463 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003464 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003465 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003466}
3467
3468
3469Address Proxy::proxy() {
ager@chromium.org3e875802009-06-29 08:26:34 +00003470 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kProxyOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003471}
3472
3473
3474void Proxy::set_proxy(Address value) {
ager@chromium.org3e875802009-06-29 08:26:34 +00003475 WRITE_INTPTR_FIELD(this, kProxyOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003476}
3477
3478
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003479ACCESSORS(JSValue, value, Object, kValueOffset)
3480
3481
3482JSValue* JSValue::cast(Object* obj) {
3483 ASSERT(obj->IsJSValue());
3484 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3485 return reinterpret_cast<JSValue*>(obj);
3486}
3487
3488
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003489ACCESSORS(JSMessageObject, type, String, kTypeOffset)
3490ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
3491ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
3492ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
3493ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
3494SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
3495SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
3496
3497
3498JSMessageObject* JSMessageObject::cast(Object* obj) {
3499 ASSERT(obj->IsJSMessageObject());
3500 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
3501 return reinterpret_cast<JSMessageObject*>(obj);
3502}
3503
3504
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003505INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003506ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003507ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003508
3509
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003510byte* Code::instruction_start() {
3511 return FIELD_ADDR(this, kHeaderSize);
3512}
3513
3514
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003515byte* Code::instruction_end() {
3516 return instruction_start() + instruction_size();
3517}
3518
3519
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003520int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003521 return RoundUp(instruction_size(), kObjectAlignment);
3522}
3523
3524
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003525FixedArray* Code::unchecked_deoptimization_data() {
3526 return reinterpret_cast<FixedArray*>(
3527 READ_FIELD(this, kDeoptimizationDataOffset));
3528}
3529
3530
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003531ByteArray* Code::unchecked_relocation_info() {
3532 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003533}
3534
3535
3536byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003537 return unchecked_relocation_info()->GetDataStartAddress();
3538}
3539
3540
3541int Code::relocation_size() {
3542 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003543}
3544
3545
3546byte* Code::entry() {
3547 return instruction_start();
3548}
3549
3550
3551bool Code::contains(byte* pc) {
3552 return (instruction_start() <= pc) &&
ricow@chromium.org65fae842010-08-25 15:26:24 +00003553 (pc <= instruction_start() + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003554}
3555
3556
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003557ACCESSORS(JSArray, length, Object, kLengthOffset)
3558
3559
ager@chromium.org236ad962008-09-25 09:45:57 +00003560ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00003561
3562
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003563JSRegExp::Type JSRegExp::TypeTag() {
3564 Object* data = this->data();
3565 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
3566 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
3567 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00003568}
3569
3570
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00003571int JSRegExp::CaptureCount() {
3572 switch (TypeTag()) {
3573 case ATOM:
3574 return 0;
3575 case IRREGEXP:
3576 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
3577 default:
3578 UNREACHABLE();
3579 return -1;
3580 }
3581}
3582
3583
ager@chromium.orga74f0da2008-12-03 16:05:52 +00003584JSRegExp::Flags JSRegExp::GetFlags() {
3585 ASSERT(this->data()->IsFixedArray());
3586 Object* data = this->data();
3587 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
3588 return Flags(smi->value());
3589}
3590
3591
3592String* JSRegExp::Pattern() {
3593 ASSERT(this->data()->IsFixedArray());
3594 Object* data = this->data();
3595 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
3596 return pattern;
3597}
3598
3599
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003600Object* JSRegExp::DataAt(int index) {
3601 ASSERT(TypeTag() != NOT_COMPILED);
3602 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00003603}
3604
3605
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003606void JSRegExp::SetDataAt(int index, Object* value) {
3607 ASSERT(TypeTag() != NOT_COMPILED);
3608 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
3609 FixedArray::cast(data())->set(index, value);
3610}
3611
3612
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003613JSObject::ElementsKind JSObject::GetElementsKind() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003614 if (map()->has_fast_elements()) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003615 ASSERT(elements()->map() == GetHeap()->fixed_array_map() ||
3616 elements()->map() == GetHeap()->fixed_cow_array_map());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003617 return FAST_ELEMENTS;
3618 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003619 HeapObject* array = elements();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003620 if (array->IsFixedArray()) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003621 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a
3622 // FixedArray, but FAST_ELEMENTS is already handled above.
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003623 ASSERT(array->IsDictionary());
3624 return DICTIONARY_ELEMENTS;
3625 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003626 ASSERT(!map()->has_fast_elements());
ager@chromium.org3811b432009-10-28 14:53:37 +00003627 if (array->IsExternalArray()) {
3628 switch (array->map()->instance_type()) {
3629 case EXTERNAL_BYTE_ARRAY_TYPE:
3630 return EXTERNAL_BYTE_ELEMENTS;
3631 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
3632 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3633 case EXTERNAL_SHORT_ARRAY_TYPE:
3634 return EXTERNAL_SHORT_ELEMENTS;
3635 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
3636 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3637 case EXTERNAL_INT_ARRAY_TYPE:
3638 return EXTERNAL_INT_ELEMENTS;
3639 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
3640 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003641 case EXTERNAL_PIXEL_ARRAY_TYPE:
3642 return EXTERNAL_PIXEL_ELEMENTS;
ager@chromium.org3811b432009-10-28 14:53:37 +00003643 default:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003644 break;
ager@chromium.org3811b432009-10-28 14:53:37 +00003645 }
3646 }
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003647 ASSERT(array->map()->instance_type() == EXTERNAL_FLOAT_ARRAY_TYPE);
3648 return EXTERNAL_FLOAT_ELEMENTS;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003649}
3650
3651
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003652bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003653 return GetElementsKind() == FAST_ELEMENTS;
3654}
3655
3656
3657bool JSObject::HasDictionaryElements() {
3658 return GetElementsKind() == DICTIONARY_ELEMENTS;
3659}
3660
3661
ager@chromium.org3811b432009-10-28 14:53:37 +00003662bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003663 HeapObject* array = elements();
3664 ASSERT(array != NULL);
3665 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00003666}
3667
3668
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003669#define EXTERNAL_ELEMENTS_CHECK(name, type) \
3670bool JSObject::HasExternal##name##Elements() { \
3671 HeapObject* array = elements(); \
3672 ASSERT(array != NULL); \
3673 if (!array->IsHeapObject()) \
3674 return false; \
3675 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00003676}
3677
3678
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003679EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
3680EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
3681EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
3682EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
3683 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
3684EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
3685EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
3686 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
3687EXTERNAL_ELEMENTS_CHECK(Float,
3688 EXTERNAL_FLOAT_ARRAY_TYPE)
3689EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00003690
3691
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003692bool JSObject::HasNamedInterceptor() {
3693 return map()->has_named_interceptor();
3694}
3695
3696
3697bool JSObject::HasIndexedInterceptor() {
3698 return map()->has_indexed_interceptor();
3699}
3700
3701
ager@chromium.org5c838252010-02-19 08:53:10 +00003702bool JSObject::AllowsSetElementsLength() {
3703 bool result = elements()->IsFixedArray();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003704 ASSERT(result == !HasExternalArrayElements());
ager@chromium.org5c838252010-02-19 08:53:10 +00003705 return result;
3706}
3707
3708
lrn@chromium.org303ada72010-10-27 09:33:13 +00003709MaybeObject* JSObject::EnsureWritableFastElements() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003710 ASSERT(HasFastElements());
3711 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003712 Isolate* isolate = GetIsolate();
3713 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003714 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003715 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
3716 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00003717 if (!maybe_writable_elems->ToObject(&writable_elems)) {
3718 return maybe_writable_elems;
3719 }
3720 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003721 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003722 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003723 return writable_elems;
3724}
3725
3726
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003727StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003728 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003729 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003730}
3731
3732
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003733NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003734 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003735 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003736}
3737
3738
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003739bool String::IsHashFieldComputed(uint32_t field) {
3740 return (field & kHashNotComputedMask) == 0;
3741}
3742
3743
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003744bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003745 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003746}
3747
3748
3749uint32_t String::Hash() {
3750 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003751 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003752 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003753 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003754 return ComputeAndSetHash();
3755}
3756
3757
ager@chromium.org7c537e22008-10-16 08:43:32 +00003758StringHasher::StringHasher(int length)
3759 : length_(length),
3760 raw_running_hash_(0),
3761 array_index_(0),
3762 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
3763 is_first_char_(true),
3764 is_valid_(true) { }
3765
3766
3767bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003768 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00003769}
3770
3771
3772void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003773 // Use the Jenkins one-at-a-time hash function to update the hash
3774 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003775 raw_running_hash_ += c;
3776 raw_running_hash_ += (raw_running_hash_ << 10);
3777 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003778 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003779 if (is_array_index_) {
3780 if (c < '0' || c > '9') {
3781 is_array_index_ = false;
3782 } else {
3783 int d = c - '0';
3784 if (is_first_char_) {
3785 is_first_char_ = false;
3786 if (c == '0' && length_ > 1) {
3787 is_array_index_ = false;
3788 return;
3789 }
3790 }
3791 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
3792 is_array_index_ = false;
3793 } else {
3794 array_index_ = array_index_ * 10 + d;
3795 }
3796 }
3797 }
3798}
3799
3800
3801void StringHasher::AddCharacterNoIndex(uc32 c) {
3802 ASSERT(!is_array_index());
3803 raw_running_hash_ += c;
3804 raw_running_hash_ += (raw_running_hash_ << 10);
3805 raw_running_hash_ ^= (raw_running_hash_ >> 6);
3806}
3807
3808
3809uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003810 // Get the calculated raw hash value and do some more bit ops to distribute
3811 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003812 uint32_t result = raw_running_hash_;
3813 result += (result << 3);
3814 result ^= (result >> 11);
3815 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003816 if (result == 0) {
3817 result = 27;
3818 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00003819 return result;
3820}
3821
3822
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003823template <typename schar>
3824uint32_t HashSequentialString(const schar* chars, int length) {
3825 StringHasher hasher(length);
3826 if (!hasher.has_trivial_hash()) {
3827 int i;
3828 for (i = 0; hasher.is_array_index() && (i < length); i++) {
3829 hasher.AddCharacter(chars[i]);
3830 }
3831 for (; i < length; i++) {
3832 hasher.AddCharacterNoIndex(chars[i]);
3833 }
3834 }
3835 return hasher.GetHashField();
3836}
3837
3838
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003839bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003840 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003841 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
3842 return false;
3843 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003844 return SlowAsArrayIndex(index);
3845}
3846
3847
3848Object* JSObject::GetPrototype() {
3849 return JSObject::cast(this)->map()->prototype();
3850}
3851
3852
3853PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
3854 return GetPropertyAttributeWithReceiver(this, key);
3855}
3856
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003857// TODO(504): this may be useful in other places too where JSGlobalProxy
3858// is used.
3859Object* JSObject::BypassGlobalProxy() {
3860 if (IsJSGlobalProxy()) {
3861 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003862 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003863 ASSERT(proto->IsJSGlobalObject());
3864 return proto;
3865 }
3866 return this;
3867}
3868
3869
3870bool JSObject::HasHiddenPropertiesObject() {
3871 ASSERT(!IsJSGlobalProxy());
3872 return GetPropertyAttributePostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003873 GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003874 false) != ABSENT;
3875}
3876
3877
3878Object* JSObject::GetHiddenPropertiesObject() {
3879 ASSERT(!IsJSGlobalProxy());
3880 PropertyAttributes attributes;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003881 // You can't install a getter on a property indexed by the hidden symbol,
3882 // so we can be sure that GetLocalPropertyPostInterceptor returns a real
3883 // object.
3884 Object* result =
3885 GetLocalPropertyPostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003886 GetHeap()->hidden_symbol(),
lrn@chromium.org303ada72010-10-27 09:33:13 +00003887 &attributes)->ToObjectUnchecked();
3888 return result;
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003889}
3890
3891
lrn@chromium.org303ada72010-10-27 09:33:13 +00003892MaybeObject* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003893 ASSERT(!IsJSGlobalProxy());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003894 return SetPropertyPostInterceptor(GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003895 hidden_obj,
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00003896 DONT_ENUM,
3897 kNonStrictMode);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003898}
3899
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003900
3901bool JSObject::HasElement(uint32_t index) {
3902 return HasElementWithReceiver(this, index);
3903}
3904
3905
3906bool AccessorInfo::all_can_read() {
3907 return BooleanBit::get(flag(), kAllCanReadBit);
3908}
3909
3910
3911void AccessorInfo::set_all_can_read(bool value) {
3912 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
3913}
3914
3915
3916bool AccessorInfo::all_can_write() {
3917 return BooleanBit::get(flag(), kAllCanWriteBit);
3918}
3919
3920
3921void AccessorInfo::set_all_can_write(bool value) {
3922 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
3923}
3924
3925
ager@chromium.org870a0b62008-11-04 11:43:05 +00003926bool AccessorInfo::prohibits_overwriting() {
3927 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
3928}
3929
3930
3931void AccessorInfo::set_prohibits_overwriting(bool value) {
3932 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
3933}
3934
3935
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003936PropertyAttributes AccessorInfo::property_attributes() {
3937 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
3938}
3939
3940
3941void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
3942 ASSERT(AttributesField::is_valid(attributes));
3943 int rest_value = flag()->value() & ~AttributesField::mask();
3944 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
3945}
3946
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00003947
3948template<typename Shape, typename Key>
3949void Dictionary<Shape, Key>::SetEntry(int entry,
3950 Object* key,
3951 Object* value) {
3952 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
3953}
3954
3955
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003956template<typename Shape, typename Key>
3957void Dictionary<Shape, Key>::SetEntry(int entry,
3958 Object* key,
3959 Object* value,
3960 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00003961 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003962 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00003963 AssertNoAllocation no_gc;
3964 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003965 FixedArray::set(index, key, mode);
3966 FixedArray::set(index+1, value, mode);
3967 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003968}
3969
3970
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003971bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
3972 ASSERT(other->IsNumber());
3973 return key == static_cast<uint32_t>(other->Number());
3974}
3975
3976
3977uint32_t NumberDictionaryShape::Hash(uint32_t key) {
3978 return ComputeIntegerHash(key);
3979}
3980
3981
3982uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
3983 ASSERT(other->IsNumber());
3984 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
3985}
3986
3987
3988MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
3989 return Isolate::Current()->heap()->NumberFromUint32(key);
3990}
3991
3992
3993bool StringDictionaryShape::IsMatch(String* key, Object* other) {
3994 // We know that all entries in a hash table had their hash keys created.
3995 // Use that knowledge to have fast failure.
3996 if (key->Hash() != String::cast(other)->Hash()) return false;
3997 return key->Equals(String::cast(other));
3998}
3999
4000
4001uint32_t StringDictionaryShape::Hash(String* key) {
4002 return key->Hash();
4003}
4004
4005
4006uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4007 return String::cast(other)->Hash();
4008}
4009
4010
4011MaybeObject* StringDictionaryShape::AsObject(String* key) {
4012 return key;
4013}
4014
4015
4016void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004017 // No write barrier is needed since empty_fixed_array is not in new space.
4018 // Please note this function is used during marking:
4019 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004020 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4021 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004022}
4023
4024
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004025void JSArray::EnsureSize(int required_size) {
4026 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004027 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004028 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4029 if (elts->length() < required_size) {
4030 // Doubling in size would be overkill, but leave some slack to avoid
4031 // constantly growing.
4032 Expand(required_size + (required_size >> 3));
4033 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004034 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004035 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4036 // Expand will allocate a new backing store in new space even if the size
4037 // we asked for isn't larger than what we had before.
4038 Expand(required_size);
4039 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004040}
4041
4042
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004043void JSArray::set_length(Smi* length) {
4044 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4045}
4046
4047
ager@chromium.org7c537e22008-10-16 08:43:32 +00004048void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004049 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004050 set_elements(storage);
4051}
4052
4053
lrn@chromium.org303ada72010-10-27 09:33:13 +00004054MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004055 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004056 return GetHeap()->CopyFixedArray(this);
4057}
4058
4059
4060Relocatable::Relocatable(Isolate* isolate) {
4061 ASSERT(isolate == Isolate::Current());
4062 isolate_ = isolate;
4063 prev_ = isolate->relocatable_top();
4064 isolate->set_relocatable_top(this);
4065}
4066
4067
4068Relocatable::~Relocatable() {
4069 ASSERT(isolate_ == Isolate::Current());
4070 ASSERT_EQ(isolate_->relocatable_top(), this);
4071 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004072}
4073
4074
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004075int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4076 return map->instance_size();
4077}
4078
4079
4080void Proxy::ProxyIterateBody(ObjectVisitor* v) {
4081 v->VisitExternalReference(
4082 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
4083}
4084
4085
4086template<typename StaticVisitor>
4087void Proxy::ProxyIterateBody() {
4088 StaticVisitor::VisitExternalReference(
4089 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
4090}
4091
4092
4093void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4094 typedef v8::String::ExternalAsciiStringResource Resource;
4095 v->VisitExternalAsciiString(
4096 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4097}
4098
4099
4100template<typename StaticVisitor>
4101void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4102 typedef v8::String::ExternalAsciiStringResource Resource;
4103 StaticVisitor::VisitExternalAsciiString(
4104 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4105}
4106
4107
4108void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4109 typedef v8::String::ExternalStringResource Resource;
4110 v->VisitExternalTwoByteString(
4111 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4112}
4113
4114
4115template<typename StaticVisitor>
4116void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4117 typedef v8::String::ExternalStringResource Resource;
4118 StaticVisitor::VisitExternalTwoByteString(
4119 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4120}
4121
4122#define SLOT_ADDR(obj, offset) \
4123 reinterpret_cast<Object**>((obj)->address() + offset)
4124
4125template<int start_offset, int end_offset, int size>
4126void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4127 HeapObject* obj,
4128 ObjectVisitor* v) {
4129 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4130}
4131
4132
4133template<int start_offset>
4134void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4135 int object_size,
4136 ObjectVisitor* v) {
4137 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4138}
4139
4140#undef SLOT_ADDR
4141
4142
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004143#undef CAST_ACCESSOR
4144#undef INT_ACCESSORS
4145#undef SMI_ACCESSORS
4146#undef ACCESSORS
4147#undef FIELD_ADDR
4148#undef READ_FIELD
4149#undef WRITE_FIELD
4150#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004151#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004152#undef READ_MEMADDR_FIELD
4153#undef WRITE_MEMADDR_FIELD
4154#undef READ_DOUBLE_FIELD
4155#undef WRITE_DOUBLE_FIELD
4156#undef READ_INT_FIELD
4157#undef WRITE_INT_FIELD
4158#undef READ_SHORT_FIELD
4159#undef WRITE_SHORT_FIELD
4160#undef READ_BYTE_FIELD
4161#undef WRITE_BYTE_FIELD
4162
4163
4164} } // namespace v8::internal
4165
4166#endif // V8_OBJECTS_INL_H_