blob: c96bf56f9fbde5228973e6d00ba8bb0431365e49 [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
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000409bool Object::IsExternalDoubleArray() {
410 return Object::IsHeapObject() &&
411 HeapObject::cast(this)->map()->instance_type() ==
412 EXTERNAL_DOUBLE_ARRAY_TYPE;
413}
414
415
lrn@chromium.org303ada72010-10-27 09:33:13 +0000416bool MaybeObject::IsFailure() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000417 return HAS_FAILURE_TAG(this);
418}
419
420
lrn@chromium.org303ada72010-10-27 09:33:13 +0000421bool MaybeObject::IsRetryAfterGC() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000422 return HAS_FAILURE_TAG(this)
423 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
424}
425
426
lrn@chromium.org303ada72010-10-27 09:33:13 +0000427bool MaybeObject::IsOutOfMemory() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000428 return HAS_FAILURE_TAG(this)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000429 && Failure::cast(this)->IsOutOfMemoryException();
ager@chromium.org7c537e22008-10-16 08:43:32 +0000430}
431
432
lrn@chromium.org303ada72010-10-27 09:33:13 +0000433bool MaybeObject::IsException() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000434 return this == Failure::Exception();
435}
436
437
lrn@chromium.org303ada72010-10-27 09:33:13 +0000438bool MaybeObject::IsTheHole() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000439 return !IsFailure() && ToObjectUnchecked()->IsTheHole();
lrn@chromium.org303ada72010-10-27 09:33:13 +0000440}
441
442
443Failure* Failure::cast(MaybeObject* obj) {
444 ASSERT(HAS_FAILURE_TAG(obj));
445 return reinterpret_cast<Failure*>(obj);
446}
447
448
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000449bool Object::IsJSObject() {
450 return IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000451 && HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000452}
453
454
ager@chromium.org32912102009-01-16 10:38:43 +0000455bool Object::IsJSContextExtensionObject() {
456 return IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000457 && (HeapObject::cast(this)->map()->instance_type() ==
458 JS_CONTEXT_EXTENSION_OBJECT_TYPE);
ager@chromium.org32912102009-01-16 10:38:43 +0000459}
460
461
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000462bool Object::IsMap() {
463 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000464 && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000465}
466
467
468bool Object::IsFixedArray() {
469 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000470 && HeapObject::cast(this)->map()->instance_type() == FIXED_ARRAY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000471}
472
473
474bool Object::IsDescriptorArray() {
475 return IsFixedArray();
476}
477
478
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000479bool Object::IsDeoptimizationInputData() {
480 // Must be a fixed array.
481 if (!IsFixedArray()) return false;
482
483 // There's no sure way to detect the difference between a fixed array and
484 // a deoptimization data array. Since this is used for asserts we can
485 // check that the length is zero or else the fixed size plus a multiple of
486 // the entry size.
487 int length = FixedArray::cast(this)->length();
488 if (length == 0) return true;
489
490 length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
491 return length >= 0 &&
492 length % DeoptimizationInputData::kDeoptEntrySize == 0;
493}
494
495
496bool Object::IsDeoptimizationOutputData() {
497 if (!IsFixedArray()) return false;
498 // There's actually no way to see the difference between a fixed array and
499 // a deoptimization data array. Since this is used for asserts we can check
500 // that the length is plausible though.
501 if (FixedArray::cast(this)->length() % 2 != 0) return false;
502 return true;
503}
504
505
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000506bool Object::IsContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000507 if (Object::IsHeapObject()) {
508 Heap* heap = HeapObject::cast(this)->GetHeap();
509 return (HeapObject::cast(this)->map() == heap->context_map() ||
510 HeapObject::cast(this)->map() == heap->catch_context_map() ||
511 HeapObject::cast(this)->map() == heap->global_context_map());
512 }
513 return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000514}
515
516
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000517bool Object::IsCatchContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000518 return Object::IsHeapObject() &&
519 HeapObject::cast(this)->map() ==
520 HeapObject::cast(this)->GetHeap()->catch_context_map();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000521}
522
523
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000524bool Object::IsGlobalContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000525 return Object::IsHeapObject() &&
526 HeapObject::cast(this)->map() ==
527 HeapObject::cast(this)->GetHeap()->global_context_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000528}
529
530
531bool Object::IsJSFunction() {
532 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000533 && HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000534}
535
536
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000537template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000538 return obj->IsJSFunction();
539}
540
541
542bool Object::IsCode() {
543 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000544 && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000545}
546
547
548bool Object::IsOddball() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000549 ASSERT(HEAP->is_safe_to_read_maps());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000550 return Object::IsHeapObject()
551 && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE;
552}
553
554
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000555bool Object::IsJSGlobalPropertyCell() {
556 return Object::IsHeapObject()
557 && HeapObject::cast(this)->map()->instance_type()
558 == JS_GLOBAL_PROPERTY_CELL_TYPE;
559}
560
561
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000562bool Object::IsSharedFunctionInfo() {
563 return Object::IsHeapObject() &&
564 (HeapObject::cast(this)->map()->instance_type() ==
565 SHARED_FUNCTION_INFO_TYPE);
566}
567
568
569bool Object::IsJSValue() {
570 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000571 && HeapObject::cast(this)->map()->instance_type() == JS_VALUE_TYPE;
572}
573
574
575bool Object::IsJSMessageObject() {
576 return Object::IsHeapObject()
577 && (HeapObject::cast(this)->map()->instance_type() ==
578 JS_MESSAGE_OBJECT_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000579}
580
581
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000582bool Object::IsStringWrapper() {
583 return IsJSValue() && JSValue::cast(this)->value()->IsString();
584}
585
586
vegorov@chromium.org7304bca2011-05-16 12:14:13 +0000587bool Object::IsJSProxy() {
588 return Object::IsHeapObject()
589 && HeapObject::cast(this)->map()->instance_type() == JS_PROXY_TYPE;
590}
591
592
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000593bool Object::IsProxy() {
594 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000595 && HeapObject::cast(this)->map()->instance_type() == PROXY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000596}
597
598
599bool Object::IsBoolean() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000600 return IsOddball() &&
601 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000602}
603
604
605bool Object::IsJSArray() {
606 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000607 && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000608}
609
610
ager@chromium.org236ad962008-09-25 09:45:57 +0000611bool Object::IsJSRegExp() {
612 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000613 && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
ager@chromium.org236ad962008-09-25 09:45:57 +0000614}
615
616
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000617template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000618 return obj->IsJSArray();
619}
620
621
622bool Object::IsHashTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000623 return Object::IsHeapObject() &&
624 HeapObject::cast(this)->map() ==
625 HeapObject::cast(this)->GetHeap()->hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000626}
627
628
629bool Object::IsDictionary() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000630 return IsHashTable() && this !=
631 HeapObject::cast(this)->GetHeap()->symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000632}
633
634
635bool Object::IsSymbolTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000636 return IsHashTable() && this ==
637 HeapObject::cast(this)->GetHeap()->raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000638}
639
640
ager@chromium.orgac091b72010-05-05 07:34:42 +0000641bool Object::IsJSFunctionResultCache() {
642 if (!IsFixedArray()) return false;
643 FixedArray* self = FixedArray::cast(this);
644 int length = self->length();
645 if (length < JSFunctionResultCache::kEntriesIndex) return false;
646 if ((length - JSFunctionResultCache::kEntriesIndex)
647 % JSFunctionResultCache::kEntrySize != 0) {
648 return false;
649 }
650#ifdef DEBUG
651 reinterpret_cast<JSFunctionResultCache*>(this)->JSFunctionResultCacheVerify();
652#endif
653 return true;
654}
655
656
ricow@chromium.org65fae842010-08-25 15:26:24 +0000657bool Object::IsNormalizedMapCache() {
658 if (!IsFixedArray()) return false;
659 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
660 return false;
661 }
662#ifdef DEBUG
663 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
664#endif
665 return true;
666}
667
668
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000669bool Object::IsCompilationCacheTable() {
670 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000671}
672
673
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000674bool Object::IsCodeCacheHashTable() {
675 return IsHashTable();
676}
677
678
ager@chromium.org236ad962008-09-25 09:45:57 +0000679bool Object::IsMapCache() {
680 return IsHashTable();
681}
682
683
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000684bool Object::IsPrimitive() {
685 return IsOddball() || IsNumber() || IsString();
686}
687
688
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000689bool Object::IsJSGlobalProxy() {
690 bool result = IsHeapObject() &&
691 (HeapObject::cast(this)->map()->instance_type() ==
692 JS_GLOBAL_PROXY_TYPE);
693 ASSERT(!result || IsAccessCheckNeeded());
694 return result;
695}
696
697
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000698bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000699 if (!IsHeapObject()) return false;
700
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000701 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000702 return type == JS_GLOBAL_OBJECT_TYPE ||
703 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000704}
705
706
707bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000708 return IsHeapObject() &&
709 (HeapObject::cast(this)->map()->instance_type() ==
710 JS_GLOBAL_OBJECT_TYPE);
711}
712
713
714bool Object::IsJSBuiltinsObject() {
715 return IsHeapObject() &&
716 (HeapObject::cast(this)->map()->instance_type() ==
717 JS_BUILTINS_OBJECT_TYPE);
718}
719
720
721bool Object::IsUndetectableObject() {
722 return IsHeapObject()
723 && HeapObject::cast(this)->map()->is_undetectable();
724}
725
726
727bool Object::IsAccessCheckNeeded() {
728 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000729 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000730}
731
732
733bool Object::IsStruct() {
734 if (!IsHeapObject()) return false;
735 switch (HeapObject::cast(this)->map()->instance_type()) {
736#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
737 STRUCT_LIST(MAKE_STRUCT_CASE)
738#undef MAKE_STRUCT_CASE
739 default: return false;
740 }
741}
742
743
744#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
745 bool Object::Is##Name() { \
746 return Object::IsHeapObject() \
747 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
748 }
749 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
750#undef MAKE_STRUCT_PREDICATE
751
752
753bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000754 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000755}
756
757
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000758bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000759 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
760}
761
762
763bool Object::IsTheHole() {
764 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000765}
766
767
768bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000769 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000770}
771
772
773bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000774 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000775}
776
777
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000778bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000779 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000780}
781
782
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000783double Object::Number() {
784 ASSERT(IsNumber());
785 return IsSmi()
786 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
787 : reinterpret_cast<HeapNumber*>(this)->value();
788}
789
790
lrn@chromium.org303ada72010-10-27 09:33:13 +0000791MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000792 if (IsSmi()) return this;
793 if (IsHeapNumber()) {
794 double value = HeapNumber::cast(this)->value();
795 int int_value = FastD2I(value);
796 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
797 return Smi::FromInt(int_value);
798 }
799 }
800 return Failure::Exception();
801}
802
803
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000804bool Object::HasSpecificClassOf(String* name) {
805 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
806}
807
808
lrn@chromium.org303ada72010-10-27 09:33:13 +0000809MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000810 // GetElement can trigger a getter which can cause allocation.
811 // This was not always the case. This ASSERT is here to catch
812 // leftover incorrect uses.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000813 ASSERT(HEAP->IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000814 return GetElementWithReceiver(this, index);
815}
816
817
lrn@chromium.org303ada72010-10-27 09:33:13 +0000818Object* Object::GetElementNoExceptionThrown(uint32_t index) {
819 MaybeObject* maybe = GetElementWithReceiver(this, index);
820 ASSERT(!maybe->IsFailure());
821 Object* result = NULL; // Initialization to please compiler.
822 maybe->ToObject(&result);
823 return result;
824}
825
826
827MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000828 PropertyAttributes attributes;
829 return GetPropertyWithReceiver(this, key, &attributes);
830}
831
832
lrn@chromium.org303ada72010-10-27 09:33:13 +0000833MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000834 return GetPropertyWithReceiver(this, key, attributes);
835}
836
837
838#define FIELD_ADDR(p, offset) \
839 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
840
841#define READ_FIELD(p, offset) \
842 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
843
844#define WRITE_FIELD(p, offset, value) \
845 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
846
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000847// TODO(isolates): Pass heap in to these macros.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000848#define WRITE_BARRIER(object, offset) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000849 object->GetHeap()->RecordWrite(object->address(), offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000850
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000851// CONDITIONAL_WRITE_BARRIER must be issued after the actual
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000852// write due to the assert validating the written value.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000853#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, mode) \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000854 if (mode == UPDATE_WRITE_BARRIER) { \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000855 heap->RecordWrite(object->address(), offset); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000856 } else { \
857 ASSERT(mode == SKIP_WRITE_BARRIER); \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000858 ASSERT(heap->InNewSpace(object) || \
859 !heap->InNewSpace(READ_FIELD(object, offset)) || \
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000860 Page::FromAddress(object->address())-> \
861 IsRegionDirty(object->address() + offset)); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000862 }
863
lrn@chromium.org7516f052011-03-30 08:52:27 +0000864#ifndef V8_TARGET_ARCH_MIPS
865 #define READ_DOUBLE_FIELD(p, offset) \
866 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
867#else // V8_TARGET_ARCH_MIPS
868 // Prevent gcc from using load-double (mips ldc1) on (possibly)
869 // non-64-bit aligned HeapNumber::value.
870 static inline double read_double_field(HeapNumber* p, int offset) {
871 union conversion {
872 double d;
873 uint32_t u[2];
874 } c;
875 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
876 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
877 return c.d;
878 }
879 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
880#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000881
lrn@chromium.org7516f052011-03-30 08:52:27 +0000882
883#ifndef V8_TARGET_ARCH_MIPS
884 #define WRITE_DOUBLE_FIELD(p, offset, value) \
885 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
886#else // V8_TARGET_ARCH_MIPS
887 // Prevent gcc from using store-double (mips sdc1) on (possibly)
888 // non-64-bit aligned HeapNumber::value.
889 static inline void write_double_field(HeapNumber* p, int offset,
890 double value) {
891 union conversion {
892 double d;
893 uint32_t u[2];
894 } c;
895 c.d = value;
896 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
897 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
898 }
899 #define WRITE_DOUBLE_FIELD(p, offset, value) \
900 write_double_field(p, offset, value)
901#endif // V8_TARGET_ARCH_MIPS
902
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000903
904#define READ_INT_FIELD(p, offset) \
905 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
906
907#define WRITE_INT_FIELD(p, offset, value) \
908 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
909
ager@chromium.org3e875802009-06-29 08:26:34 +0000910#define READ_INTPTR_FIELD(p, offset) \
911 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
912
913#define WRITE_INTPTR_FIELD(p, offset, value) \
914 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
915
ager@chromium.org7c537e22008-10-16 08:43:32 +0000916#define READ_UINT32_FIELD(p, offset) \
917 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
918
919#define WRITE_UINT32_FIELD(p, offset, value) \
920 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
921
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000922#define READ_SHORT_FIELD(p, offset) \
923 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
924
925#define WRITE_SHORT_FIELD(p, offset, value) \
926 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
927
928#define READ_BYTE_FIELD(p, offset) \
929 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
930
931#define WRITE_BYTE_FIELD(p, offset, value) \
932 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
933
934
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000935Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
936 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000937}
938
939
940int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000941 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000942}
943
944
945Smi* Smi::FromInt(int value) {
946 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000947 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000948 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000949 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000950 return reinterpret_cast<Smi*>(tagged_value);
951}
952
953
954Smi* Smi::FromIntptr(intptr_t value) {
955 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000956 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
957 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000958}
959
960
961Failure::Type Failure::type() const {
962 return static_cast<Type>(value() & kFailureTypeTagMask);
963}
964
965
966bool Failure::IsInternalError() const {
967 return type() == INTERNAL_ERROR;
968}
969
970
971bool Failure::IsOutOfMemoryException() const {
972 return type() == OUT_OF_MEMORY_EXCEPTION;
973}
974
975
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000976AllocationSpace Failure::allocation_space() const {
977 ASSERT_EQ(RETRY_AFTER_GC, type());
978 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
979 & kSpaceTagMask);
980}
981
982
983Failure* Failure::InternalError() {
984 return Construct(INTERNAL_ERROR);
985}
986
987
988Failure* Failure::Exception() {
989 return Construct(EXCEPTION);
990}
991
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +0000992
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000993Failure* Failure::OutOfMemoryException() {
994 return Construct(OUT_OF_MEMORY_EXCEPTION);
995}
996
997
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000998intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000999 return static_cast<intptr_t>(
1000 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001001}
1002
1003
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001004Failure* Failure::RetryAfterGC() {
1005 return RetryAfterGC(NEW_SPACE);
1006}
1007
1008
1009Failure* Failure::RetryAfterGC(AllocationSpace space) {
1010 ASSERT((space & ~kSpaceTagMask) == 0);
1011 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001012}
1013
1014
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001015Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001016 uintptr_t info =
1017 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001018 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001019 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001020}
1021
1022
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001023bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001024#ifdef DEBUG
1025 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1026#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001027
1028#ifdef V8_TARGET_ARCH_X64
1029 // To be representable as a long smi, the value must be a 32-bit integer.
1030 bool result = (value == static_cast<int32_t>(value));
1031#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001032 // To be representable as an tagged small integer, the two
1033 // most-significant bits of 'value' must be either 00 or 11 due to
1034 // sign-extension. To check this we add 01 to the two
1035 // most-significant bits, and check if the most-significant bit is 0
1036 //
1037 // CAUTION: The original code below:
1038 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1039 // may lead to incorrect results according to the C language spec, and
1040 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1041 // compiler may produce undefined results in case of signed integer
1042 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001043 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001044#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001045 ASSERT(result == in_range);
1046 return result;
1047}
1048
1049
kasper.lund7276f142008-07-30 08:49:36 +00001050MapWord MapWord::FromMap(Map* map) {
1051 return MapWord(reinterpret_cast<uintptr_t>(map));
1052}
1053
1054
1055Map* MapWord::ToMap() {
1056 return reinterpret_cast<Map*>(value_);
1057}
1058
1059
1060bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001061 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001062}
1063
1064
1065MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001066 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1067 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001068}
1069
1070
1071HeapObject* MapWord::ToForwardingAddress() {
1072 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001073 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001074}
1075
1076
1077bool MapWord::IsMarked() {
1078 return (value_ & kMarkingMask) == 0;
1079}
1080
1081
1082void MapWord::SetMark() {
1083 value_ &= ~kMarkingMask;
1084}
1085
1086
1087void MapWord::ClearMark() {
1088 value_ |= kMarkingMask;
1089}
1090
1091
1092bool MapWord::IsOverflowed() {
1093 return (value_ & kOverflowMask) != 0;
1094}
1095
1096
1097void MapWord::SetOverflow() {
1098 value_ |= kOverflowMask;
1099}
1100
1101
1102void MapWord::ClearOverflow() {
1103 value_ &= ~kOverflowMask;
1104}
1105
1106
1107MapWord MapWord::EncodeAddress(Address map_address, int offset) {
1108 // Offset is the distance in live bytes from the first live object in the
1109 // same page. The offset between two objects in the same page should not
1110 // exceed the object area size of a page.
1111 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
1112
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001113 uintptr_t compact_offset = offset >> kObjectAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001114 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
1115
1116 Page* map_page = Page::FromAddress(map_address);
1117 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
1118
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001119 uintptr_t map_page_offset =
1120 map_page->Offset(map_address) >> kMapAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001121
1122 uintptr_t encoding =
1123 (compact_offset << kForwardingOffsetShift) |
1124 (map_page_offset << kMapPageOffsetShift) |
1125 (map_page->mc_page_index << kMapPageIndexShift);
1126 return MapWord(encoding);
1127}
1128
1129
1130Address MapWord::DecodeMapAddress(MapSpace* map_space) {
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001131 int map_page_index =
1132 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
kasper.lund7276f142008-07-30 08:49:36 +00001133 ASSERT_MAP_PAGE_INDEX(map_page_index);
1134
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001135 int map_page_offset = static_cast<int>(
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001136 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift) <<
1137 kMapAlignmentBits);
kasper.lund7276f142008-07-30 08:49:36 +00001138
1139 return (map_space->PageAddress(map_page_index) + map_page_offset);
1140}
1141
1142
1143int MapWord::DecodeOffset() {
1144 // The offset field is represented in the kForwardingOffsetBits
1145 // most-significant bits.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001146 uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
1147 ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize));
1148 return static_cast<int>(offset);
kasper.lund7276f142008-07-30 08:49:36 +00001149}
1150
1151
1152MapWord MapWord::FromEncodedAddress(Address address) {
1153 return MapWord(reinterpret_cast<uintptr_t>(address));
1154}
1155
1156
1157Address MapWord::ToEncodedAddress() {
1158 return reinterpret_cast<Address>(value_);
1159}
1160
1161
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001162#ifdef DEBUG
1163void HeapObject::VerifyObjectField(int offset) {
1164 VerifyPointer(READ_FIELD(this, offset));
1165}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001166
1167void HeapObject::VerifySmiField(int offset) {
1168 ASSERT(READ_FIELD(this, offset)->IsSmi());
1169}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001170#endif
1171
1172
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001173Heap* HeapObject::GetHeap() {
1174 // During GC, the map pointer in HeapObject is used in various ways that
1175 // prevent us from retrieving Heap from the map.
1176 // Assert that we are not in GC, implement GC code in a way that it doesn't
1177 // pull heap from the map.
1178 ASSERT(HEAP->is_safe_to_read_maps());
1179 return map()->heap();
1180}
1181
1182
1183Isolate* HeapObject::GetIsolate() {
1184 return GetHeap()->isolate();
1185}
1186
1187
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001188Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001189 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001190}
1191
1192
1193void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001194 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001195}
1196
1197
kasper.lund7276f142008-07-30 08:49:36 +00001198MapWord HeapObject::map_word() {
1199 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1200}
1201
1202
1203void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001204 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001205 // here.
1206 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1207}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001208
1209
1210HeapObject* HeapObject::FromAddress(Address address) {
1211 ASSERT_TAG_ALIGNED(address);
1212 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1213}
1214
1215
1216Address HeapObject::address() {
1217 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1218}
1219
1220
1221int HeapObject::Size() {
1222 return SizeFromMap(map());
1223}
1224
1225
1226void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1227 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1228 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1229}
1230
1231
1232void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1233 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1234}
1235
1236
kasper.lund7276f142008-07-30 08:49:36 +00001237bool HeapObject::IsMarked() {
1238 return map_word().IsMarked();
1239}
1240
1241
1242void HeapObject::SetMark() {
1243 ASSERT(!IsMarked());
1244 MapWord first_word = map_word();
1245 first_word.SetMark();
1246 set_map_word(first_word);
1247}
1248
1249
1250void HeapObject::ClearMark() {
1251 ASSERT(IsMarked());
1252 MapWord first_word = map_word();
1253 first_word.ClearMark();
1254 set_map_word(first_word);
1255}
1256
1257
1258bool HeapObject::IsOverflowed() {
1259 return map_word().IsOverflowed();
1260}
1261
1262
1263void HeapObject::SetOverflow() {
1264 MapWord first_word = map_word();
1265 first_word.SetOverflow();
1266 set_map_word(first_word);
1267}
1268
1269
1270void HeapObject::ClearOverflow() {
1271 ASSERT(IsOverflowed());
1272 MapWord first_word = map_word();
1273 first_word.ClearOverflow();
1274 set_map_word(first_word);
1275}
1276
1277
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001278double HeapNumber::value() {
1279 return READ_DOUBLE_FIELD(this, kValueOffset);
1280}
1281
1282
1283void HeapNumber::set_value(double value) {
1284 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1285}
1286
1287
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001288int HeapNumber::get_exponent() {
1289 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1290 kExponentShift) - kExponentBias;
1291}
1292
1293
1294int HeapNumber::get_sign() {
1295 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1296}
1297
1298
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001299ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001300
1301
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001302HeapObject* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001303 Object* array = READ_FIELD(this, kElementsOffset);
1304 // In the assert below Dictionary is covered under FixedArray.
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001305 ASSERT(array->IsFixedArray() || array->IsExternalArray());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001306 return reinterpret_cast<HeapObject*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001307}
1308
1309
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001310void JSObject::set_elements(HeapObject* value, WriteBarrierMode mode) {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001311 ASSERT(map()->has_fast_elements() ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001312 (value->map() == GetHeap()->fixed_array_map() ||
1313 value->map() == GetHeap()->fixed_cow_array_map()));
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001314 // In the assert below Dictionary is covered under FixedArray.
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001315 ASSERT(value->IsFixedArray() || value->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001316 WRITE_FIELD(this, kElementsOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001317 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001318}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001319
1320
1321void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001322 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1323 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001324}
1325
1326
1327void JSObject::initialize_elements() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001328 ASSERT(map()->has_fast_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001329 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1330 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001331}
1332
1333
lrn@chromium.org303ada72010-10-27 09:33:13 +00001334MaybeObject* JSObject::ResetElements() {
1335 Object* obj;
1336 { MaybeObject* maybe_obj = map()->GetFastElementsMap();
1337 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1338 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001339 set_map(Map::cast(obj));
1340 initialize_elements();
1341 return this;
1342}
1343
1344
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001345ACCESSORS(Oddball, to_string, String, kToStringOffset)
1346ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1347
1348
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001349byte Oddball::kind() {
1350 return READ_BYTE_FIELD(this, kKindOffset);
1351}
1352
1353
1354void Oddball::set_kind(byte value) {
1355 WRITE_BYTE_FIELD(this, kKindOffset, value);
1356}
1357
1358
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001359Object* JSGlobalPropertyCell::value() {
1360 return READ_FIELD(this, kValueOffset);
1361}
1362
1363
1364void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1365 // The write barrier is not used for global property cells.
1366 ASSERT(!val->IsJSGlobalPropertyCell());
1367 WRITE_FIELD(this, kValueOffset, val);
1368}
1369
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001370
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001371int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001372 InstanceType type = map()->instance_type();
1373 // Check for the most common kind of JavaScript object before
1374 // falling into the generic switch. This speeds up the internal
1375 // field operations considerably on average.
1376 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1377 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001378 case JS_GLOBAL_PROXY_TYPE:
1379 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001380 case JS_GLOBAL_OBJECT_TYPE:
1381 return JSGlobalObject::kSize;
1382 case JS_BUILTINS_OBJECT_TYPE:
1383 return JSBuiltinsObject::kSize;
1384 case JS_FUNCTION_TYPE:
1385 return JSFunction::kSize;
1386 case JS_VALUE_TYPE:
1387 return JSValue::kSize;
1388 case JS_ARRAY_TYPE:
1389 return JSValue::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001390 case JS_REGEXP_TYPE:
1391 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001392 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001393 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001394 case JS_MESSAGE_OBJECT_TYPE:
1395 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001396 default:
1397 UNREACHABLE();
1398 return 0;
1399 }
1400}
1401
1402
1403int JSObject::GetInternalFieldCount() {
1404 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001405 // Make sure to adjust for the number of in-object properties. These
1406 // properties do contribute to the size, but are not internal fields.
1407 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1408 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001409}
1410
1411
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001412int JSObject::GetInternalFieldOffset(int index) {
1413 ASSERT(index < GetInternalFieldCount() && index >= 0);
1414 return GetHeaderSize() + (kPointerSize * index);
1415}
1416
1417
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001418Object* JSObject::GetInternalField(int index) {
1419 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001420 // Internal objects do follow immediately after the header, whereas in-object
1421 // properties are at the end of the object. Therefore there is no need
1422 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001423 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1424}
1425
1426
1427void JSObject::SetInternalField(int index, Object* value) {
1428 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001429 // Internal objects do follow immediately after the header, whereas in-object
1430 // properties are at the end of the object. Therefore there is no need
1431 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001432 int offset = GetHeaderSize() + (kPointerSize * index);
1433 WRITE_FIELD(this, offset, value);
1434 WRITE_BARRIER(this, offset);
1435}
1436
1437
ager@chromium.org7c537e22008-10-16 08:43:32 +00001438// Access fast-case object properties at index. The use of these routines
1439// is needed to correctly distinguish between properties stored in-object and
1440// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001441Object* JSObject::FastPropertyAt(int index) {
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 return READ_FIELD(this, offset);
1447 } else {
1448 ASSERT(index < properties()->length());
1449 return properties()->get(index);
1450 }
1451}
1452
1453
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001454Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001455 // Adjust for the number of properties stored in the object.
1456 index -= map()->inobject_properties();
1457 if (index < 0) {
1458 int offset = map()->instance_size() + (index * kPointerSize);
1459 WRITE_FIELD(this, offset, value);
1460 WRITE_BARRIER(this, offset);
1461 } else {
1462 ASSERT(index < properties()->length());
1463 properties()->set(index, value);
1464 }
1465 return value;
1466}
1467
1468
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001469int JSObject::GetInObjectPropertyOffset(int index) {
1470 // Adjust for the number of properties stored in the object.
1471 index -= map()->inobject_properties();
1472 ASSERT(index < 0);
1473 return map()->instance_size() + (index * kPointerSize);
1474}
1475
1476
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001477Object* JSObject::InObjectPropertyAt(int index) {
1478 // Adjust for the number of properties stored in the object.
1479 index -= map()->inobject_properties();
1480 ASSERT(index < 0);
1481 int offset = map()->instance_size() + (index * kPointerSize);
1482 return READ_FIELD(this, offset);
1483}
1484
1485
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001486Object* JSObject::InObjectPropertyAtPut(int index,
1487 Object* value,
1488 WriteBarrierMode mode) {
1489 // Adjust for the number of properties stored in the object.
1490 index -= map()->inobject_properties();
1491 ASSERT(index < 0);
1492 int offset = map()->instance_size() + (index * kPointerSize);
1493 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001494 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001495 return value;
1496}
1497
1498
1499
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001500void JSObject::InitializeBody(int object_size, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001501 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001502 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001503 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001504 }
1505}
1506
1507
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001508bool JSObject::HasFastProperties() {
1509 return !properties()->IsDictionary();
1510}
1511
1512
1513int JSObject::MaxFastProperties() {
1514 // Allow extra fast properties if the object has more than
1515 // kMaxFastProperties in-object properties. When this is the case,
1516 // it is very unlikely that the object is being used as a dictionary
1517 // and there is a good chance that allowing more map transitions
1518 // will be worth it.
1519 return Max(map()->inobject_properties(), kMaxFastProperties);
1520}
1521
1522
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001523void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001524 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001525 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001526 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001527 }
1528}
1529
1530
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001531bool Object::ToArrayIndex(uint32_t* index) {
1532 if (IsSmi()) {
1533 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001534 if (value < 0) return false;
1535 *index = value;
1536 return true;
1537 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001538 if (IsHeapNumber()) {
1539 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001540 uint32_t uint_value = static_cast<uint32_t>(value);
1541 if (value == static_cast<double>(uint_value)) {
1542 *index = uint_value;
1543 return true;
1544 }
1545 }
1546 return false;
1547}
1548
1549
1550bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1551 if (!this->IsJSValue()) return false;
1552
1553 JSValue* js_value = JSValue::cast(this);
1554 if (!js_value->value()->IsString()) return false;
1555
1556 String* str = String::cast(js_value->value());
1557 if (index >= (uint32_t)str->length()) return false;
1558
1559 return true;
1560}
1561
1562
1563Object* FixedArray::get(int index) {
1564 ASSERT(index >= 0 && index < this->length());
1565 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1566}
1567
1568
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001569void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001570 ASSERT(map() != HEAP->fixed_cow_array_map());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001571 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1572 int offset = kHeaderSize + index * kPointerSize;
1573 WRITE_FIELD(this, offset, value);
1574}
1575
1576
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001577void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001578 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001579 ASSERT(index >= 0 && index < this->length());
1580 int offset = kHeaderSize + index * kPointerSize;
1581 WRITE_FIELD(this, offset, value);
1582 WRITE_BARRIER(this, offset);
1583}
1584
1585
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001586WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001587 if (GetHeap()->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001588 return UPDATE_WRITE_BARRIER;
1589}
1590
1591
1592void FixedArray::set(int index,
1593 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001594 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001595 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001596 ASSERT(index >= 0 && index < this->length());
1597 int offset = kHeaderSize + index * kPointerSize;
1598 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001599 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001600}
1601
1602
1603void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001604 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001605 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001606 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001607 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1608}
1609
1610
1611void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001612 ASSERT(map() != HEAP->fixed_cow_array_map());
1613 set_undefined(GetHeap(), index);
1614}
1615
1616
1617void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001618 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001619 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001620 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001621 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001622}
1623
1624
ager@chromium.org236ad962008-09-25 09:45:57 +00001625void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001626 set_null(GetHeap(), index);
1627}
1628
1629
1630void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001631 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001632 ASSERT(!heap->InNewSpace(heap->null_value()));
1633 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001634}
1635
1636
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001637void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001638 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001639 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001640 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1641 WRITE_FIELD(this,
1642 kHeaderSize + index * kPointerSize,
1643 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001644}
1645
1646
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001647void FixedArray::set_unchecked(int index, Smi* value) {
1648 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1649 int offset = kHeaderSize + index * kPointerSize;
1650 WRITE_FIELD(this, offset, value);
1651}
1652
1653
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001654void FixedArray::set_unchecked(Heap* heap,
1655 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001656 Object* value,
1657 WriteBarrierMode mode) {
1658 int offset = kHeaderSize + index * kPointerSize;
1659 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001660 CONDITIONAL_WRITE_BARRIER(heap, this, offset, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001661}
1662
1663
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001664void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001665 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001666 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1667 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001668}
1669
1670
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001671Object** FixedArray::data_start() {
1672 return HeapObject::RawField(this, kHeaderSize);
1673}
1674
1675
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001676bool DescriptorArray::IsEmpty() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001677 ASSERT(this->length() > kFirstIndex ||
1678 this == HEAP->empty_descriptor_array());
1679 return length() <= kFirstIndex;
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001680}
1681
1682
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001683void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1684 Object* tmp = array->get(first);
1685 fast_set(array, first, array->get(second));
1686 fast_set(array, second, tmp);
1687}
1688
1689
1690int DescriptorArray::Search(String* name) {
1691 SLOW_ASSERT(IsSortedNoDuplicates());
1692
1693 // Check for empty descriptor array.
1694 int nof = number_of_descriptors();
1695 if (nof == 0) return kNotFound;
1696
1697 // Fast case: do linear search for small arrays.
1698 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001699 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001700 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001701 }
1702
1703 // Slow case: perform binary search.
1704 return BinarySearch(name, 0, nof - 1);
1705}
1706
1707
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001708int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001709 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001710 if (number == DescriptorLookupCache::kAbsent) {
1711 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001712 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001713 }
1714 return number;
1715}
1716
1717
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001718String* DescriptorArray::GetKey(int descriptor_number) {
1719 ASSERT(descriptor_number < number_of_descriptors());
1720 return String::cast(get(ToKeyIndex(descriptor_number)));
1721}
1722
1723
1724Object* DescriptorArray::GetValue(int descriptor_number) {
1725 ASSERT(descriptor_number < number_of_descriptors());
1726 return GetContentArray()->get(ToValueIndex(descriptor_number));
1727}
1728
1729
1730Smi* DescriptorArray::GetDetails(int descriptor_number) {
1731 ASSERT(descriptor_number < number_of_descriptors());
1732 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1733}
1734
1735
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001736PropertyType DescriptorArray::GetType(int descriptor_number) {
1737 ASSERT(descriptor_number < number_of_descriptors());
1738 return PropertyDetails(GetDetails(descriptor_number)).type();
1739}
1740
1741
1742int DescriptorArray::GetFieldIndex(int descriptor_number) {
1743 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1744}
1745
1746
1747JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1748 return JSFunction::cast(GetValue(descriptor_number));
1749}
1750
1751
1752Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1753 ASSERT(GetType(descriptor_number) == CALLBACKS);
1754 return GetValue(descriptor_number);
1755}
1756
1757
1758AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1759 ASSERT(GetType(descriptor_number) == CALLBACKS);
1760 Proxy* p = Proxy::cast(GetCallbacksObject(descriptor_number));
1761 return reinterpret_cast<AccessorDescriptor*>(p->proxy());
1762}
1763
1764
1765bool DescriptorArray::IsProperty(int descriptor_number) {
1766 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1767}
1768
1769
1770bool DescriptorArray::IsTransition(int descriptor_number) {
1771 PropertyType t = GetType(descriptor_number);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001772 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION ||
1773 t == EXTERNAL_ARRAY_TRANSITION;
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001774}
1775
1776
1777bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1778 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1779}
1780
1781
1782bool DescriptorArray::IsDontEnum(int descriptor_number) {
1783 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1784}
1785
1786
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001787void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1788 desc->Init(GetKey(descriptor_number),
1789 GetValue(descriptor_number),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001790 PropertyDetails(GetDetails(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001791}
1792
1793
1794void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1795 // Range check.
1796 ASSERT(descriptor_number < number_of_descriptors());
1797
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001798 // Make sure none of the elements in desc are in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001799 ASSERT(!HEAP->InNewSpace(desc->GetKey()));
1800 ASSERT(!HEAP->InNewSpace(desc->GetValue()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001801
1802 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1803 FixedArray* content_array = GetContentArray();
1804 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1805 fast_set(content_array, ToDetailsIndex(descriptor_number),
1806 desc->GetDetails().AsSmi());
1807}
1808
1809
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001810void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1811 Descriptor desc;
1812 src->Get(src_index, &desc);
1813 Set(index, &desc);
1814}
1815
1816
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001817void DescriptorArray::Swap(int first, int second) {
1818 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1819 FixedArray* content_array = GetContentArray();
1820 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1821 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1822}
1823
1824
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001825template<typename Shape, typename Key>
1826int HashTable<Shape, Key>::FindEntry(Key key) {
1827 return FindEntry(GetIsolate(), key);
1828}
1829
1830
1831// Find entry for key otherwise return kNotFound.
1832template<typename Shape, typename Key>
1833int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
1834 uint32_t capacity = Capacity();
1835 uint32_t entry = FirstProbe(Shape::Hash(key), capacity);
1836 uint32_t count = 1;
1837 // EnsureCapacity will guarantee the hash table is never full.
1838 while (true) {
1839 Object* element = KeyAt(entry);
1840 if (element == isolate->heap()->undefined_value()) break; // Empty entry.
1841 if (element != isolate->heap()->null_value() &&
1842 Shape::IsMatch(key, element)) return entry;
1843 entry = NextProbe(entry, count++, capacity);
1844 }
1845 return kNotFound;
1846}
1847
1848
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001849bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001850 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001851 if (!max_index_object->IsSmi()) return false;
1852 return 0 !=
1853 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1854}
1855
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001856uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001857 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001858 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001859 if (!max_index_object->IsSmi()) return 0;
1860 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1861 return value >> kRequiresSlowElementsTagSize;
1862}
1863
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001864void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001865 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001866}
1867
1868
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001869// ------------------------------------
1870// Cast operations
1871
1872
1873CAST_ACCESSOR(FixedArray)
1874CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001875CAST_ACCESSOR(DeoptimizationInputData)
1876CAST_ACCESSOR(DeoptimizationOutputData)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001877CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00001878CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00001879CAST_ACCESSOR(NormalizedMapCache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00001880CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001881CAST_ACCESSOR(CodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00001882CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001883CAST_ACCESSOR(String)
1884CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00001885CAST_ACCESSOR(SeqAsciiString)
1886CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001887CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001888CAST_ACCESSOR(ExternalString)
1889CAST_ACCESSOR(ExternalAsciiString)
1890CAST_ACCESSOR(ExternalTwoByteString)
1891CAST_ACCESSOR(JSObject)
1892CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001893CAST_ACCESSOR(HeapObject)
1894CAST_ACCESSOR(HeapNumber)
1895CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001896CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001897CAST_ACCESSOR(SharedFunctionInfo)
1898CAST_ACCESSOR(Map)
1899CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001900CAST_ACCESSOR(GlobalObject)
1901CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001902CAST_ACCESSOR(JSGlobalObject)
1903CAST_ACCESSOR(JSBuiltinsObject)
1904CAST_ACCESSOR(Code)
1905CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00001906CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00001907CAST_ACCESSOR(JSProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001908CAST_ACCESSOR(Proxy)
1909CAST_ACCESSOR(ByteArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00001910CAST_ACCESSOR(ExternalArray)
1911CAST_ACCESSOR(ExternalByteArray)
1912CAST_ACCESSOR(ExternalUnsignedByteArray)
1913CAST_ACCESSOR(ExternalShortArray)
1914CAST_ACCESSOR(ExternalUnsignedShortArray)
1915CAST_ACCESSOR(ExternalIntArray)
1916CAST_ACCESSOR(ExternalUnsignedIntArray)
1917CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00001918CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001919CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001920CAST_ACCESSOR(Struct)
1921
1922
1923#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
1924 STRUCT_LIST(MAKE_STRUCT_CAST)
1925#undef MAKE_STRUCT_CAST
1926
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001927
1928template <typename Shape, typename Key>
1929HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001930 ASSERT(obj->IsHashTable());
1931 return reinterpret_cast<HashTable*>(obj);
1932}
1933
1934
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001935SMI_ACCESSORS(FixedArray, length, kLengthOffset)
1936SMI_ACCESSORS(ByteArray, length, kLengthOffset)
1937
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001938INT_ACCESSORS(ExternalArray, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001939
1940
ager@chromium.orgac091b72010-05-05 07:34:42 +00001941SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001942
1943
1944uint32_t String::hash_field() {
1945 return READ_UINT32_FIELD(this, kHashFieldOffset);
1946}
1947
1948
1949void String::set_hash_field(uint32_t value) {
1950 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001951#if V8_HOST_ARCH_64_BIT
1952 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
1953#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001954}
1955
1956
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001957bool String::Equals(String* other) {
1958 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001959 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
1960 return false;
1961 }
1962 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001963}
1964
1965
lrn@chromium.org303ada72010-10-27 09:33:13 +00001966MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001967 if (!StringShape(this).IsCons()) return this;
1968 ConsString* cons = ConsString::cast(this);
1969 if (cons->second()->length() == 0) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001970 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001971}
1972
1973
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001974String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00001975 MaybeObject* flat = TryFlatten(pretenure);
1976 Object* successfully_flattened;
1977 if (flat->ToObject(&successfully_flattened)) {
1978 return String::cast(successfully_flattened);
1979 }
1980 return this;
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001981}
1982
1983
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001984uint16_t String::Get(int index) {
1985 ASSERT(index >= 0 && index < length());
1986 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001987 case kSeqStringTag | kAsciiStringTag:
1988 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
1989 case kSeqStringTag | kTwoByteStringTag:
1990 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
1991 case kConsStringTag | kAsciiStringTag:
1992 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001993 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00001994 case kExternalStringTag | kAsciiStringTag:
1995 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
1996 case kExternalStringTag | kTwoByteStringTag:
1997 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001998 default:
1999 break;
2000 }
2001
2002 UNREACHABLE();
2003 return 0;
2004}
2005
2006
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002007void String::Set(int index, uint16_t value) {
2008 ASSERT(index >= 0 && index < length());
2009 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002010
ager@chromium.org5ec48922009-05-05 07:25:34 +00002011 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002012 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2013 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002014}
2015
2016
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002017bool String::IsFlat() {
2018 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002019 case kConsStringTag: {
2020 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00002021 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00002022 return second->length() == 0;
2023 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00002024 default:
2025 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002026 }
2027}
2028
2029
ager@chromium.org7c537e22008-10-16 08:43:32 +00002030uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002031 ASSERT(index >= 0 && index < length());
2032 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2033}
2034
2035
ager@chromium.org7c537e22008-10-16 08:43:32 +00002036void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002037 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2038 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2039 static_cast<byte>(value));
2040}
2041
2042
ager@chromium.org7c537e22008-10-16 08:43:32 +00002043Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002044 return FIELD_ADDR(this, kHeaderSize);
2045}
2046
2047
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002048char* SeqAsciiString::GetChars() {
2049 return reinterpret_cast<char*>(GetCharsAddress());
2050}
2051
2052
ager@chromium.org7c537e22008-10-16 08:43:32 +00002053Address SeqTwoByteString::GetCharsAddress() {
2054 return FIELD_ADDR(this, kHeaderSize);
2055}
2056
2057
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002058uc16* SeqTwoByteString::GetChars() {
2059 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2060}
2061
2062
ager@chromium.org7c537e22008-10-16 08:43:32 +00002063uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002064 ASSERT(index >= 0 && index < length());
2065 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2066}
2067
2068
ager@chromium.org7c537e22008-10-16 08:43:32 +00002069void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002070 ASSERT(index >= 0 && index < length());
2071 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2072}
2073
2074
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002075int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002076 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002077}
2078
2079
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002080int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002081 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002082}
2083
2084
ager@chromium.org870a0b62008-11-04 11:43:05 +00002085String* ConsString::first() {
2086 return String::cast(READ_FIELD(this, kFirstOffset));
2087}
2088
2089
2090Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002091 return READ_FIELD(this, kFirstOffset);
2092}
2093
2094
ager@chromium.org870a0b62008-11-04 11:43:05 +00002095void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002096 WRITE_FIELD(this, kFirstOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002097 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002098}
2099
2100
ager@chromium.org870a0b62008-11-04 11:43:05 +00002101String* ConsString::second() {
2102 return String::cast(READ_FIELD(this, kSecondOffset));
2103}
2104
2105
2106Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002107 return READ_FIELD(this, kSecondOffset);
2108}
2109
2110
ager@chromium.org870a0b62008-11-04 11:43:05 +00002111void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002112 WRITE_FIELD(this, kSecondOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002113 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002114}
2115
2116
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002117ExternalAsciiString::Resource* ExternalAsciiString::resource() {
2118 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2119}
2120
2121
2122void ExternalAsciiString::set_resource(
2123 ExternalAsciiString::Resource* resource) {
2124 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2125}
2126
2127
2128ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
2129 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2130}
2131
2132
2133void ExternalTwoByteString::set_resource(
2134 ExternalTwoByteString::Resource* resource) {
2135 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2136}
2137
2138
ager@chromium.orgac091b72010-05-05 07:34:42 +00002139void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002140 set_finger_index(kEntriesIndex);
2141 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002142}
2143
2144
2145void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002146 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002147 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002148 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002149 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002150 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002151 MakeZeroSize();
2152}
2153
2154
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002155int JSFunctionResultCache::size() {
2156 return Smi::cast(get(kCacheSizeIndex))->value();
2157}
2158
2159
2160void JSFunctionResultCache::set_size(int size) {
2161 set(kCacheSizeIndex, Smi::FromInt(size));
2162}
2163
2164
2165int JSFunctionResultCache::finger_index() {
2166 return Smi::cast(get(kFingerIndex))->value();
2167}
2168
2169
2170void JSFunctionResultCache::set_finger_index(int finger_index) {
2171 set(kFingerIndex, Smi::FromInt(finger_index));
2172}
2173
2174
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002175byte ByteArray::get(int index) {
2176 ASSERT(index >= 0 && index < this->length());
2177 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2178}
2179
2180
2181void ByteArray::set(int index, byte value) {
2182 ASSERT(index >= 0 && index < this->length());
2183 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2184}
2185
2186
2187int ByteArray::get_int(int index) {
2188 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2189 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2190}
2191
2192
2193ByteArray* ByteArray::FromDataStartAddress(Address address) {
2194 ASSERT_TAG_ALIGNED(address);
2195 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2196}
2197
2198
2199Address ByteArray::GetDataStartAddress() {
2200 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2201}
2202
2203
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002204uint8_t* ExternalPixelArray::external_pixel_pointer() {
2205 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002206}
2207
2208
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002209uint8_t ExternalPixelArray::get(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002210 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002211 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002212 return ptr[index];
2213}
2214
2215
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002216void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002217 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002218 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002219 ptr[index] = value;
2220}
2221
2222
ager@chromium.org3811b432009-10-28 14:53:37 +00002223void* ExternalArray::external_pointer() {
2224 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2225 return reinterpret_cast<void*>(ptr);
2226}
2227
2228
2229void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2230 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2231 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2232}
2233
2234
2235int8_t ExternalByteArray::get(int index) {
2236 ASSERT((index >= 0) && (index < this->length()));
2237 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2238 return ptr[index];
2239}
2240
2241
2242void ExternalByteArray::set(int index, int8_t value) {
2243 ASSERT((index >= 0) && (index < this->length()));
2244 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2245 ptr[index] = value;
2246}
2247
2248
2249uint8_t ExternalUnsignedByteArray::get(int index) {
2250 ASSERT((index >= 0) && (index < this->length()));
2251 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2252 return ptr[index];
2253}
2254
2255
2256void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2257 ASSERT((index >= 0) && (index < this->length()));
2258 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2259 ptr[index] = value;
2260}
2261
2262
2263int16_t ExternalShortArray::get(int index) {
2264 ASSERT((index >= 0) && (index < this->length()));
2265 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2266 return ptr[index];
2267}
2268
2269
2270void ExternalShortArray::set(int index, int16_t value) {
2271 ASSERT((index >= 0) && (index < this->length()));
2272 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2273 ptr[index] = value;
2274}
2275
2276
2277uint16_t ExternalUnsignedShortArray::get(int index) {
2278 ASSERT((index >= 0) && (index < this->length()));
2279 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2280 return ptr[index];
2281}
2282
2283
2284void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2285 ASSERT((index >= 0) && (index < this->length()));
2286 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2287 ptr[index] = value;
2288}
2289
2290
2291int32_t ExternalIntArray::get(int index) {
2292 ASSERT((index >= 0) && (index < this->length()));
2293 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2294 return ptr[index];
2295}
2296
2297
2298void ExternalIntArray::set(int index, int32_t value) {
2299 ASSERT((index >= 0) && (index < this->length()));
2300 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2301 ptr[index] = value;
2302}
2303
2304
2305uint32_t ExternalUnsignedIntArray::get(int index) {
2306 ASSERT((index >= 0) && (index < this->length()));
2307 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2308 return ptr[index];
2309}
2310
2311
2312void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2313 ASSERT((index >= 0) && (index < this->length()));
2314 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2315 ptr[index] = value;
2316}
2317
2318
2319float ExternalFloatArray::get(int index) {
2320 ASSERT((index >= 0) && (index < this->length()));
2321 float* ptr = static_cast<float*>(external_pointer());
2322 return ptr[index];
2323}
2324
2325
2326void ExternalFloatArray::set(int index, float value) {
2327 ASSERT((index >= 0) && (index < this->length()));
2328 float* ptr = static_cast<float*>(external_pointer());
2329 ptr[index] = value;
2330}
2331
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002332
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002333double ExternalDoubleArray::get(int index) {
2334 ASSERT((index >= 0) && (index < this->length()));
2335 double* ptr = static_cast<double*>(external_pointer());
2336 return ptr[index];
2337}
2338
2339
2340void ExternalDoubleArray::set(int index, double value) {
2341 ASSERT((index >= 0) && (index < this->length()));
2342 double* ptr = static_cast<double*>(external_pointer());
2343 ptr[index] = value;
2344}
2345
2346
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002347int Map::visitor_id() {
2348 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2349}
2350
2351
2352void Map::set_visitor_id(int id) {
2353 ASSERT(0 <= id && id < 256);
2354 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2355}
2356
ager@chromium.org3811b432009-10-28 14:53:37 +00002357
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002358int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002359 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2360}
2361
2362
2363int Map::inobject_properties() {
2364 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002365}
2366
2367
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002368int Map::pre_allocated_property_fields() {
2369 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2370}
2371
2372
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002373int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002374 int instance_size = map->instance_size();
2375 if (instance_size != kVariableSizeSentinel) return instance_size;
2376 // We can ignore the "symbol" bit becase it is only set for symbols
2377 // and implies a string type.
2378 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002379 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002380 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002381 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002382 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002383 if (instance_type == ASCII_STRING_TYPE) {
2384 return SeqAsciiString::SizeFor(
2385 reinterpret_cast<SeqAsciiString*>(this)->length());
2386 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002387 if (instance_type == BYTE_ARRAY_TYPE) {
2388 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2389 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002390 if (instance_type == STRING_TYPE) {
2391 return SeqTwoByteString::SizeFor(
2392 reinterpret_cast<SeqTwoByteString*>(this)->length());
2393 }
2394 ASSERT(instance_type == CODE_TYPE);
2395 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002396}
2397
2398
2399void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002400 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002401 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002402 ASSERT(0 <= value && value < 256);
2403 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2404}
2405
2406
ager@chromium.org7c537e22008-10-16 08:43:32 +00002407void Map::set_inobject_properties(int value) {
2408 ASSERT(0 <= value && value < 256);
2409 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2410}
2411
2412
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002413void Map::set_pre_allocated_property_fields(int value) {
2414 ASSERT(0 <= value && value < 256);
2415 WRITE_BYTE_FIELD(this,
2416 kPreAllocatedPropertyFieldsOffset,
2417 static_cast<byte>(value));
2418}
2419
2420
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002421InstanceType Map::instance_type() {
2422 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2423}
2424
2425
2426void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002427 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2428}
2429
2430
2431int Map::unused_property_fields() {
2432 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2433}
2434
2435
2436void Map::set_unused_property_fields(int value) {
2437 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2438}
2439
2440
2441byte Map::bit_field() {
2442 return READ_BYTE_FIELD(this, kBitFieldOffset);
2443}
2444
2445
2446void Map::set_bit_field(byte value) {
2447 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2448}
2449
2450
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002451byte Map::bit_field2() {
2452 return READ_BYTE_FIELD(this, kBitField2Offset);
2453}
2454
2455
2456void Map::set_bit_field2(byte value) {
2457 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2458}
2459
2460
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002461void Map::set_non_instance_prototype(bool value) {
2462 if (value) {
2463 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2464 } else {
2465 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2466 }
2467}
2468
2469
2470bool Map::has_non_instance_prototype() {
2471 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2472}
2473
2474
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002475void Map::set_function_with_prototype(bool value) {
2476 if (value) {
2477 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2478 } else {
2479 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2480 }
2481}
2482
2483
2484bool Map::function_with_prototype() {
2485 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2486}
2487
2488
ager@chromium.org870a0b62008-11-04 11:43:05 +00002489void Map::set_is_access_check_needed(bool access_check_needed) {
2490 if (access_check_needed) {
2491 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2492 } else {
2493 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2494 }
2495}
2496
2497
2498bool Map::is_access_check_needed() {
2499 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2500}
2501
2502
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002503void Map::set_is_extensible(bool value) {
2504 if (value) {
2505 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2506 } else {
2507 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2508 }
2509}
2510
2511bool Map::is_extensible() {
2512 return ((1 << kIsExtensible) & bit_field2()) != 0;
2513}
2514
2515
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002516void Map::set_attached_to_shared_function_info(bool value) {
2517 if (value) {
2518 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2519 } else {
2520 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2521 }
2522}
2523
2524bool Map::attached_to_shared_function_info() {
2525 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2526}
2527
2528
2529void Map::set_is_shared(bool value) {
2530 if (value) {
2531 set_bit_field2(bit_field2() | (1 << kIsShared));
2532 } else {
2533 set_bit_field2(bit_field2() & ~(1 << kIsShared));
2534 }
2535}
2536
2537bool Map::is_shared() {
2538 return ((1 << kIsShared) & bit_field2()) != 0;
2539}
2540
2541
2542JSFunction* Map::unchecked_constructor() {
2543 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2544}
2545
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002546
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002547FixedArray* Map::unchecked_prototype_transitions() {
2548 return reinterpret_cast<FixedArray*>(
2549 READ_FIELD(this, kPrototypeTransitionsOffset));
2550}
2551
2552
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002553Code::Flags Code::flags() {
2554 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2555}
2556
2557
2558void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002559 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002560 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002561 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2562 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002563 ExtractArgumentsCountFromFlags(flags) >= 0);
2564 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2565}
2566
2567
2568Code::Kind Code::kind() {
2569 return ExtractKindFromFlags(flags());
2570}
2571
2572
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002573InLoopFlag Code::ic_in_loop() {
2574 return ExtractICInLoopFromFlags(flags());
2575}
2576
2577
kasper.lund7276f142008-07-30 08:49:36 +00002578InlineCacheState Code::ic_state() {
2579 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002580 // Only allow uninitialized or debugger states for non-IC code
2581 // objects. This is used in the debugger to determine whether or not
2582 // a call to code object has been replaced with a debug break call.
2583 ASSERT(is_inline_cache_stub() ||
2584 result == UNINITIALIZED ||
2585 result == DEBUG_BREAK ||
2586 result == DEBUG_PREPARE_STEP_IN);
2587 return result;
2588}
2589
2590
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002591Code::ExtraICState Code::extra_ic_state() {
2592 ASSERT(is_inline_cache_stub());
2593 return ExtractExtraICStateFromFlags(flags());
2594}
2595
2596
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002597PropertyType Code::type() {
kasper.lund7276f142008-07-30 08:49:36 +00002598 ASSERT(ic_state() == MONOMORPHIC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002599 return ExtractTypeFromFlags(flags());
2600}
2601
2602
2603int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002604 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002605 return ExtractArgumentsCountFromFlags(flags());
2606}
2607
2608
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002609int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002610 ASSERT(kind() == STUB ||
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002611 kind() == TYPE_RECORDING_BINARY_OP_IC ||
2612 kind() == COMPARE_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002613 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002614}
2615
2616
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002617void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002618 ASSERT(kind() == STUB ||
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002619 kind() == TYPE_RECORDING_UNARY_OP_IC ||
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002620 kind() == TYPE_RECORDING_BINARY_OP_IC ||
2621 kind() == COMPARE_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002622 ASSERT(0 <= major && major < 256);
2623 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002624}
2625
2626
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002627bool Code::optimizable() {
2628 ASSERT(kind() == FUNCTION);
2629 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2630}
2631
2632
2633void Code::set_optimizable(bool value) {
2634 ASSERT(kind() == FUNCTION);
2635 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2636}
2637
2638
2639bool Code::has_deoptimization_support() {
2640 ASSERT(kind() == FUNCTION);
2641 return READ_BYTE_FIELD(this, kHasDeoptimizationSupportOffset) == 1;
2642}
2643
2644
2645void Code::set_has_deoptimization_support(bool value) {
2646 ASSERT(kind() == FUNCTION);
2647 WRITE_BYTE_FIELD(this, kHasDeoptimizationSupportOffset, value ? 1 : 0);
2648}
2649
2650
2651int Code::allow_osr_at_loop_nesting_level() {
2652 ASSERT(kind() == FUNCTION);
2653 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
2654}
2655
2656
2657void Code::set_allow_osr_at_loop_nesting_level(int level) {
2658 ASSERT(kind() == FUNCTION);
2659 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
2660 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
2661}
2662
2663
2664unsigned Code::stack_slots() {
2665 ASSERT(kind() == OPTIMIZED_FUNCTION);
2666 return READ_UINT32_FIELD(this, kStackSlotsOffset);
2667}
2668
2669
2670void Code::set_stack_slots(unsigned slots) {
2671 ASSERT(kind() == OPTIMIZED_FUNCTION);
2672 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
2673}
2674
2675
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002676unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002677 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002678 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002679}
2680
2681
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002682void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002683 ASSERT(kind() == OPTIMIZED_FUNCTION);
2684 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002685 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002686}
2687
2688
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002689unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002690 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002691 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002692}
2693
2694
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002695void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002696 ASSERT(kind() == FUNCTION);
2697 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002698 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002699}
2700
2701
2702CheckType Code::check_type() {
2703 ASSERT(is_call_stub() || is_keyed_call_stub());
2704 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
2705 return static_cast<CheckType>(type);
2706}
2707
2708
2709void Code::set_check_type(CheckType value) {
2710 ASSERT(is_call_stub() || is_keyed_call_stub());
2711 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
2712}
2713
2714
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002715ExternalArrayType Code::external_array_type() {
2716 ASSERT(is_external_array_load_stub() || is_external_array_store_stub());
2717 byte type = READ_BYTE_FIELD(this, kExternalArrayTypeOffset);
2718 return static_cast<ExternalArrayType>(type);
2719}
2720
2721
2722void Code::set_external_array_type(ExternalArrayType value) {
2723 ASSERT(is_external_array_load_stub() || is_external_array_store_stub());
2724 WRITE_BYTE_FIELD(this, kExternalArrayTypeOffset, value);
2725}
2726
2727
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002728byte Code::type_recording_unary_op_type() {
2729 ASSERT(is_type_recording_unary_op_stub());
2730 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
2731}
2732
2733
2734void Code::set_type_recording_unary_op_type(byte value) {
2735 ASSERT(is_type_recording_unary_op_stub());
2736 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
2737}
2738
2739
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002740byte Code::type_recording_binary_op_type() {
2741 ASSERT(is_type_recording_binary_op_stub());
2742 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
2743}
2744
2745
2746void Code::set_type_recording_binary_op_type(byte value) {
2747 ASSERT(is_type_recording_binary_op_stub());
2748 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
2749}
2750
2751
2752byte Code::type_recording_binary_op_result_type() {
2753 ASSERT(is_type_recording_binary_op_stub());
2754 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
2755}
2756
2757
2758void Code::set_type_recording_binary_op_result_type(byte value) {
2759 ASSERT(is_type_recording_binary_op_stub());
2760 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
2761}
2762
2763
2764byte Code::compare_state() {
2765 ASSERT(is_compare_ic_stub());
2766 return READ_BYTE_FIELD(this, kCompareStateOffset);
2767}
2768
2769
2770void Code::set_compare_state(byte value) {
2771 ASSERT(is_compare_ic_stub());
2772 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
2773}
2774
2775
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002776bool Code::is_inline_cache_stub() {
2777 Kind kind = this->kind();
2778 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2779}
2780
2781
2782Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002783 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002784 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002785 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002786 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002787 int argc,
2788 InlineCacheHolderFlag holder) {
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002789 // Extra IC state is only allowed for monomorphic call IC stubs
2790 // or for store IC stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002791 ASSERT(extra_ic_state == kNoExtraICState ||
2792 (kind == CALL_IC && (ic_state == MONOMORPHIC ||
sgjesse@chromium.org496c03a2011-02-14 12:05:43 +00002793 ic_state == MONOMORPHIC_PROTOTYPE_FAILURE)) ||
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00002794 (kind == STORE_IC) ||
karlklose@chromium.org83a47282011-05-11 11:54:09 +00002795 (kind == KEYED_STORE_IC) ||
2796 (kind == KEYED_EXTERNAL_ARRAY_STORE_IC));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002797 // Compute the bit mask.
2798 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002799 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002800 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002801 bits |= type << kFlagsTypeShift;
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002802 bits |= extra_ic_state << kFlagsExtraICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002803 bits |= argc << kFlagsArgumentsCountShift;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002804 if (holder == PROTOTYPE_MAP) bits |= kFlagsCacheInPrototypeMapMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002805 // Cast to flags and validate result before returning it.
2806 Flags result = static_cast<Flags>(bits);
2807 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002808 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002809 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002810 ASSERT(ExtractTypeFromFlags(result) == type);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002811 ASSERT(ExtractExtraICStateFromFlags(result) == extra_ic_state);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002812 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2813 return result;
2814}
2815
2816
2817Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2818 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002819 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002820 InlineCacheHolderFlag holder,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002821 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002822 int argc) {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002823 return ComputeFlags(
2824 kind, in_loop, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002825}
2826
2827
2828Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2829 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2830 return static_cast<Kind>(bits);
2831}
2832
2833
kasper.lund7276f142008-07-30 08:49:36 +00002834InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2835 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002836 return static_cast<InlineCacheState>(bits);
2837}
2838
2839
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002840Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
2841 int bits = (flags & kFlagsExtraICStateMask) >> kFlagsExtraICStateShift;
2842 return static_cast<ExtraICState>(bits);
2843}
2844
2845
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002846InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2847 int bits = (flags & kFlagsICInLoopMask);
2848 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2849}
2850
2851
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002852PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2853 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2854 return static_cast<PropertyType>(bits);
2855}
2856
2857
2858int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2859 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2860}
2861
2862
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002863InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
2864 int bits = (flags & kFlagsCacheInPrototypeMapMask);
2865 return bits != 0 ? PROTOTYPE_MAP : OWN_MAP;
2866}
2867
2868
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002869Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2870 int bits = flags & ~kFlagsTypeMask;
2871 return static_cast<Flags>(bits);
2872}
2873
2874
ager@chromium.org8bb60582008-12-11 12:02:20 +00002875Code* Code::GetCodeFromTargetAddress(Address address) {
2876 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2877 // GetCodeFromTargetAddress might be called when marking objects during mark
2878 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2879 // Code::cast. Code::cast does not work when the object's map is
2880 // marked.
2881 Code* result = reinterpret_cast<Code*>(code);
2882 return result;
2883}
2884
2885
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002886Isolate* Map::isolate() {
2887 return heap()->isolate();
2888}
2889
2890
2891Heap* Map::heap() {
2892 // NOTE: address() helper is not used to save one instruction.
2893 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
2894 ASSERT(heap != NULL);
2895 ASSERT(heap->isolate() == Isolate::Current());
2896 return heap;
2897}
2898
2899
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002900Heap* Code::heap() {
2901 // NOTE: address() helper is not used to save one instruction.
2902 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
2903 ASSERT(heap != NULL);
2904 ASSERT(heap->isolate() == Isolate::Current());
2905 return heap;
2906}
2907
2908
2909Isolate* Code::isolate() {
2910 return heap()->isolate();
2911}
2912
2913
2914Heap* JSGlobalPropertyCell::heap() {
2915 // NOTE: address() helper is not used to save one instruction.
2916 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
2917 ASSERT(heap != NULL);
2918 ASSERT(heap->isolate() == Isolate::Current());
2919 return heap;
2920}
2921
2922
2923Isolate* JSGlobalPropertyCell::isolate() {
2924 return heap()->isolate();
2925}
2926
2927
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002928Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
2929 return HeapObject::
2930 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
2931}
2932
2933
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002934Object* Map::prototype() {
2935 return READ_FIELD(this, kPrototypeOffset);
2936}
2937
2938
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002939void Map::set_prototype(Object* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002940 ASSERT(value->IsNull() || value->IsJSObject());
2941 WRITE_FIELD(this, kPrototypeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002942 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002943}
2944
2945
lrn@chromium.org303ada72010-10-27 09:33:13 +00002946MaybeObject* Map::GetFastElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002947 if (has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00002948 Object* obj;
2949 { MaybeObject* maybe_obj = CopyDropTransitions();
2950 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2951 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002952 Map* new_map = Map::cast(obj);
2953 new_map->set_has_fast_elements(true);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002954 isolate()->counters()->map_slow_to_fast_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002955 return new_map;
2956}
2957
2958
lrn@chromium.org303ada72010-10-27 09:33:13 +00002959MaybeObject* Map::GetSlowElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002960 if (!has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00002961 Object* obj;
2962 { MaybeObject* maybe_obj = CopyDropTransitions();
2963 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2964 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002965 Map* new_map = Map::cast(obj);
2966 new_map->set_has_fast_elements(false);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002967 isolate()->counters()->map_fast_to_slow_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002968 return new_map;
2969}
2970
2971
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002972ACCESSORS(Map, instance_descriptors, DescriptorArray,
2973 kInstanceDescriptorsOffset)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002974ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002975ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002976ACCESSORS(Map, constructor, Object, kConstructorOffset)
2977
2978ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
2979ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002980ACCESSORS_GCSAFE(JSFunction, next_function_link, Object,
2981 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002982
2983ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
2984ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002985ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002986
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002987ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002988
2989ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
2990ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
2991ACCESSORS(AccessorInfo, data, Object, kDataOffset)
2992ACCESSORS(AccessorInfo, name, Object, kNameOffset)
2993ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
2994
2995ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
2996ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
2997ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
2998
2999ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3000ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3001ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3002ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3003ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3004ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3005
3006ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3007ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3008
3009ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3010ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3011
3012ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3013ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003014ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3015 kPropertyAccessorsOffset)
3016ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3017 kPrototypeTemplateOffset)
3018ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3019ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3020 kNamedPropertyHandlerOffset)
3021ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3022 kIndexedPropertyHandlerOffset)
3023ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3024 kInstanceTemplateOffset)
3025ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3026ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003027ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3028 kInstanceCallHandlerOffset)
3029ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3030 kAccessCheckInfoOffset)
3031ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
3032
3033ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003034ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3035 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003036
3037ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3038ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3039
3040ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3041
3042ACCESSORS(Script, source, Object, kSourceOffset)
3043ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003044ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003045ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3046ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003047ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003048ACCESSORS(Script, context_data, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003049ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
3050ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003051ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003052ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003053ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003054ACCESSORS(Script, eval_from_instructions_offset, Smi,
3055 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003056
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003057#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003058ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3059ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3060ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3061ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3062
3063ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3064ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3065ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3066ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003067#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003068
3069ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003070ACCESSORS_GCSAFE(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3071ACCESSORS_GCSAFE(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003072ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3073 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003074ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003075ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3076ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003077ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003078ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3079 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003080
3081BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3082 kHiddenPrototypeBit)
3083BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3084BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3085 kNeedsAccessCheckBit)
3086BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3087 kIsExpressionBit)
3088BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3089 kIsTopLevelBit)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003090BOOL_GETTER(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003091 has_only_simple_this_property_assignments,
3092 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003093BOOL_ACCESSORS(SharedFunctionInfo,
3094 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003095 allows_lazy_compilation,
3096 kAllowLazyCompilation)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003097
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003098
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003099#if V8_HOST_ARCH_32_BIT
3100SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3101SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003102 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003103SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003104 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003105SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3106SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003107 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003108SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3109SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003110 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003111SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003112 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003113SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003114 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003115SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003116#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003117
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003118#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003119 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003120 int holder::name() { \
3121 int value = READ_INT_FIELD(this, offset); \
3122 ASSERT(kHeapObjectTag == 1); \
3123 ASSERT((value & kHeapObjectTag) == 0); \
3124 return value >> 1; \
3125 } \
3126 void holder::set_##name(int value) { \
3127 ASSERT(kHeapObjectTag == 1); \
3128 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3129 (value & 0xC0000000) == 0x000000000); \
3130 WRITE_INT_FIELD(this, \
3131 offset, \
3132 (value << 1) & ~kHeapObjectTag); \
3133 }
3134
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003135#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3136 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003137 INT_ACCESSORS(holder, name, offset)
3138
3139
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003140PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003141PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3142 formal_parameter_count,
3143 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003144
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003145PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3146 expected_nof_properties,
3147 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003148PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3149
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003150PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3151PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3152 start_position_and_type,
3153 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003154
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003155PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3156 function_token_position,
3157 kFunctionTokenPositionOffset)
3158PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3159 compiler_hints,
3160 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003161
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003162PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3163 this_property_assignments_count,
3164 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003165PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003166#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003167
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003168
3169int SharedFunctionInfo::construction_count() {
3170 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3171}
3172
3173
3174void SharedFunctionInfo::set_construction_count(int value) {
3175 ASSERT(0 <= value && value < 256);
3176 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3177}
3178
3179
3180bool SharedFunctionInfo::live_objects_may_exist() {
3181 return (compiler_hints() & (1 << kLiveObjectsMayExist)) != 0;
3182}
3183
3184
3185void SharedFunctionInfo::set_live_objects_may_exist(bool value) {
3186 if (value) {
3187 set_compiler_hints(compiler_hints() | (1 << kLiveObjectsMayExist));
3188 } else {
3189 set_compiler_hints(compiler_hints() & ~(1 << kLiveObjectsMayExist));
3190 }
3191}
3192
3193
3194bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003195 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003196}
3197
3198
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003199bool SharedFunctionInfo::optimization_disabled() {
3200 return BooleanBit::get(compiler_hints(), kOptimizationDisabled);
3201}
3202
3203
3204void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3205 set_compiler_hints(BooleanBit::set(compiler_hints(),
3206 kOptimizationDisabled,
3207 disable));
3208 // If disabling optimizations we reflect that in the code object so
3209 // it will not be counted as optimizable code.
3210 if ((code()->kind() == Code::FUNCTION) && disable) {
3211 code()->set_optimizable(false);
3212 }
3213}
3214
3215
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003216bool SharedFunctionInfo::strict_mode() {
3217 return BooleanBit::get(compiler_hints(), kStrictModeFunction);
3218}
3219
3220
3221void SharedFunctionInfo::set_strict_mode(bool value) {
3222 set_compiler_hints(BooleanBit::set(compiler_hints(),
3223 kStrictModeFunction,
3224 value));
3225}
3226
3227
ricow@chromium.org6fe7a8e2011-05-13 07:57:29 +00003228bool SharedFunctionInfo::es5_native() {
3229 return BooleanBit::get(compiler_hints(), kES5Native);
3230}
3231
3232
3233void SharedFunctionInfo::set_es5_native(bool value) {
3234 set_compiler_hints(BooleanBit::set(compiler_hints(),
3235 kES5Native,
3236 value));
3237}
3238
3239
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003240ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3241ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3242
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003243bool Script::HasValidSource() {
3244 Object* src = this->source();
3245 if (!src->IsString()) return true;
3246 String* src_str = String::cast(src);
3247 if (!StringShape(src_str).IsExternal()) return true;
3248 if (src_str->IsAsciiRepresentation()) {
3249 return ExternalAsciiString::cast(src)->resource() != NULL;
3250 } else if (src_str->IsTwoByteRepresentation()) {
3251 return ExternalTwoByteString::cast(src)->resource() != NULL;
3252 }
3253 return true;
3254}
3255
3256
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003257void SharedFunctionInfo::DontAdaptArguments() {
3258 ASSERT(code()->kind() == Code::BUILTIN);
3259 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3260}
3261
3262
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003263int SharedFunctionInfo::start_position() {
3264 return start_position_and_type() >> kStartPositionShift;
3265}
3266
3267
3268void SharedFunctionInfo::set_start_position(int start_position) {
3269 set_start_position_and_type((start_position << kStartPositionShift)
3270 | (start_position_and_type() & ~kStartPositionMask));
3271}
3272
3273
3274Code* SharedFunctionInfo::code() {
3275 return Code::cast(READ_FIELD(this, kCodeOffset));
3276}
3277
3278
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003279Code* SharedFunctionInfo::unchecked_code() {
3280 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3281}
3282
3283
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003284void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003285 WRITE_FIELD(this, kCodeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003286 ASSERT(!Isolate::Current()->heap()->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003287}
3288
3289
ager@chromium.orgb5737492010-07-15 09:29:43 +00003290SerializedScopeInfo* SharedFunctionInfo::scope_info() {
3291 return reinterpret_cast<SerializedScopeInfo*>(
3292 READ_FIELD(this, kScopeInfoOffset));
3293}
3294
3295
3296void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
3297 WriteBarrierMode mode) {
3298 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003299 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kScopeInfoOffset, mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003300}
3301
3302
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003303Smi* SharedFunctionInfo::deopt_counter() {
3304 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3305}
3306
3307
3308void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3309 WRITE_FIELD(this, kDeoptCounterOffset, value);
3310}
3311
3312
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003313bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003314 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003315 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003316}
3317
3318
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003319bool SharedFunctionInfo::IsApiFunction() {
3320 return function_data()->IsFunctionTemplateInfo();
3321}
3322
3323
3324FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3325 ASSERT(IsApiFunction());
3326 return FunctionTemplateInfo::cast(function_data());
3327}
3328
3329
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003330bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003331 return function_data()->IsSmi();
3332}
3333
3334
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003335BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3336 ASSERT(HasBuiltinFunctionId());
3337 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003338}
3339
3340
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003341int SharedFunctionInfo::code_age() {
3342 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3343}
3344
3345
3346void SharedFunctionInfo::set_code_age(int code_age) {
3347 set_compiler_hints(compiler_hints() |
3348 ((code_age & kCodeAgeMask) << kCodeAgeShift));
3349}
3350
3351
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003352bool SharedFunctionInfo::has_deoptimization_support() {
3353 Code* code = this->code();
3354 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3355}
3356
3357
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003358bool JSFunction::IsBuiltin() {
3359 return context()->global()->IsJSBuiltinsObject();
3360}
3361
3362
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003363bool JSFunction::NeedsArgumentsAdaption() {
3364 return shared()->formal_parameter_count() !=
3365 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3366}
3367
3368
3369bool JSFunction::IsOptimized() {
3370 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3371}
3372
3373
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003374bool JSFunction::IsOptimizable() {
3375 return code()->kind() == Code::FUNCTION && code()->optimizable();
3376}
3377
3378
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003379bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003380 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003381}
3382
3383
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003384Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003385 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003386}
3387
3388
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003389Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003390 return reinterpret_cast<Code*>(
3391 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003392}
3393
3394
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003395void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00003396 // Skip the write barrier because code is never in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003397 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003398 Address entry = value->entry();
3399 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003400}
3401
3402
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003403void JSFunction::ReplaceCode(Code* code) {
3404 bool was_optimized = IsOptimized();
3405 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3406
3407 set_code(code);
3408
3409 // Add/remove the function from the list of optimized functions for this
3410 // context based on the state change.
3411 if (!was_optimized && is_optimized) {
3412 context()->global_context()->AddOptimizedFunction(this);
3413 }
3414 if (was_optimized && !is_optimized) {
3415 context()->global_context()->RemoveOptimizedFunction(this);
3416 }
3417}
3418
3419
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003420Context* JSFunction::context() {
3421 return Context::cast(READ_FIELD(this, kContextOffset));
3422}
3423
3424
3425Object* JSFunction::unchecked_context() {
3426 return READ_FIELD(this, kContextOffset);
3427}
3428
3429
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003430SharedFunctionInfo* JSFunction::unchecked_shared() {
3431 return reinterpret_cast<SharedFunctionInfo*>(
3432 READ_FIELD(this, kSharedFunctionInfoOffset));
3433}
3434
3435
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003436void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003437 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003438 WRITE_FIELD(this, kContextOffset, value);
3439 WRITE_BARRIER(this, kContextOffset);
3440}
3441
3442ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3443 kPrototypeOrInitialMapOffset)
3444
3445
3446Map* JSFunction::initial_map() {
3447 return Map::cast(prototype_or_initial_map());
3448}
3449
3450
3451void JSFunction::set_initial_map(Map* value) {
3452 set_prototype_or_initial_map(value);
3453}
3454
3455
3456bool JSFunction::has_initial_map() {
3457 return prototype_or_initial_map()->IsMap();
3458}
3459
3460
3461bool JSFunction::has_instance_prototype() {
3462 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3463}
3464
3465
3466bool JSFunction::has_prototype() {
3467 return map()->has_non_instance_prototype() || has_instance_prototype();
3468}
3469
3470
3471Object* JSFunction::instance_prototype() {
3472 ASSERT(has_instance_prototype());
3473 if (has_initial_map()) return initial_map()->prototype();
3474 // When there is no initial map and the prototype is a JSObject, the
3475 // initial map field is used for the prototype field.
3476 return prototype_or_initial_map();
3477}
3478
3479
3480Object* JSFunction::prototype() {
3481 ASSERT(has_prototype());
3482 // If the function's prototype property has been set to a non-JSObject
3483 // value, that value is stored in the constructor field of the map.
3484 if (map()->has_non_instance_prototype()) return map()->constructor();
3485 return instance_prototype();
3486}
3487
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003488bool JSFunction::should_have_prototype() {
3489 return map()->function_with_prototype();
3490}
3491
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003492
3493bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003494 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003495}
3496
3497
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003498int JSFunction::NumberOfLiterals() {
3499 return literals()->length();
3500}
3501
3502
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003503Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003504 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003505 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003506}
3507
3508
3509void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3510 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003511 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003512 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
3513 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
3514}
3515
3516
3517Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003518 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003519 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3520}
3521
3522
3523void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3524 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003525 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003526 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003527 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003528}
3529
3530
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003531ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
3532
3533
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003534Address Proxy::proxy() {
ager@chromium.org3e875802009-06-29 08:26:34 +00003535 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kProxyOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003536}
3537
3538
3539void Proxy::set_proxy(Address value) {
ager@chromium.org3e875802009-06-29 08:26:34 +00003540 WRITE_INTPTR_FIELD(this, kProxyOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003541}
3542
3543
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003544ACCESSORS(JSValue, value, Object, kValueOffset)
3545
3546
3547JSValue* JSValue::cast(Object* obj) {
3548 ASSERT(obj->IsJSValue());
3549 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3550 return reinterpret_cast<JSValue*>(obj);
3551}
3552
3553
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003554ACCESSORS(JSMessageObject, type, String, kTypeOffset)
3555ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
3556ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
3557ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
3558ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
3559SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
3560SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
3561
3562
3563JSMessageObject* JSMessageObject::cast(Object* obj) {
3564 ASSERT(obj->IsJSMessageObject());
3565 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
3566 return reinterpret_cast<JSMessageObject*>(obj);
3567}
3568
3569
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003570INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003571ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003572ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003573ACCESSORS(Code, next_code_flushing_candidate,
3574 Object, kNextCodeFlushingCandidateOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003575
3576
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003577byte* Code::instruction_start() {
3578 return FIELD_ADDR(this, kHeaderSize);
3579}
3580
3581
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003582byte* Code::instruction_end() {
3583 return instruction_start() + instruction_size();
3584}
3585
3586
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003587int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003588 return RoundUp(instruction_size(), kObjectAlignment);
3589}
3590
3591
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003592FixedArray* Code::unchecked_deoptimization_data() {
3593 return reinterpret_cast<FixedArray*>(
3594 READ_FIELD(this, kDeoptimizationDataOffset));
3595}
3596
3597
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003598ByteArray* Code::unchecked_relocation_info() {
3599 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003600}
3601
3602
3603byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003604 return unchecked_relocation_info()->GetDataStartAddress();
3605}
3606
3607
3608int Code::relocation_size() {
3609 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003610}
3611
3612
3613byte* Code::entry() {
3614 return instruction_start();
3615}
3616
3617
3618bool Code::contains(byte* pc) {
3619 return (instruction_start() <= pc) &&
ricow@chromium.org65fae842010-08-25 15:26:24 +00003620 (pc <= instruction_start() + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003621}
3622
3623
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003624ACCESSORS(JSArray, length, Object, kLengthOffset)
3625
3626
ager@chromium.org236ad962008-09-25 09:45:57 +00003627ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00003628
3629
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003630JSRegExp::Type JSRegExp::TypeTag() {
3631 Object* data = this->data();
3632 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
3633 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
3634 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00003635}
3636
3637
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00003638int JSRegExp::CaptureCount() {
3639 switch (TypeTag()) {
3640 case ATOM:
3641 return 0;
3642 case IRREGEXP:
3643 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
3644 default:
3645 UNREACHABLE();
3646 return -1;
3647 }
3648}
3649
3650
ager@chromium.orga74f0da2008-12-03 16:05:52 +00003651JSRegExp::Flags JSRegExp::GetFlags() {
3652 ASSERT(this->data()->IsFixedArray());
3653 Object* data = this->data();
3654 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
3655 return Flags(smi->value());
3656}
3657
3658
3659String* JSRegExp::Pattern() {
3660 ASSERT(this->data()->IsFixedArray());
3661 Object* data = this->data();
3662 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
3663 return pattern;
3664}
3665
3666
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003667Object* JSRegExp::DataAt(int index) {
3668 ASSERT(TypeTag() != NOT_COMPILED);
3669 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00003670}
3671
3672
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003673void JSRegExp::SetDataAt(int index, Object* value) {
3674 ASSERT(TypeTag() != NOT_COMPILED);
3675 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
3676 FixedArray::cast(data())->set(index, value);
3677}
3678
3679
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003680JSObject::ElementsKind JSObject::GetElementsKind() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003681 if (map()->has_fast_elements()) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003682 ASSERT(elements()->map() == GetHeap()->fixed_array_map() ||
3683 elements()->map() == GetHeap()->fixed_cow_array_map());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003684 return FAST_ELEMENTS;
3685 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003686 HeapObject* array = elements();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003687 if (array->IsFixedArray()) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003688 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a
3689 // FixedArray, but FAST_ELEMENTS is already handled above.
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003690 ASSERT(array->IsDictionary());
3691 return DICTIONARY_ELEMENTS;
3692 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003693 ASSERT(!map()->has_fast_elements());
ager@chromium.org3811b432009-10-28 14:53:37 +00003694 if (array->IsExternalArray()) {
3695 switch (array->map()->instance_type()) {
3696 case EXTERNAL_BYTE_ARRAY_TYPE:
3697 return EXTERNAL_BYTE_ELEMENTS;
3698 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
3699 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3700 case EXTERNAL_SHORT_ARRAY_TYPE:
3701 return EXTERNAL_SHORT_ELEMENTS;
3702 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
3703 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3704 case EXTERNAL_INT_ARRAY_TYPE:
3705 return EXTERNAL_INT_ELEMENTS;
3706 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
3707 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003708 case EXTERNAL_FLOAT_ARRAY_TYPE:
3709 return EXTERNAL_FLOAT_ELEMENTS;
3710 case EXTERNAL_DOUBLE_ARRAY_TYPE:
3711 return EXTERNAL_DOUBLE_ELEMENTS;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003712 case EXTERNAL_PIXEL_ARRAY_TYPE:
3713 return EXTERNAL_PIXEL_ELEMENTS;
ager@chromium.org3811b432009-10-28 14:53:37 +00003714 default:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003715 break;
ager@chromium.org3811b432009-10-28 14:53:37 +00003716 }
3717 }
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003718 UNREACHABLE();
3719 return DICTIONARY_ELEMENTS;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003720}
3721
3722
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003723bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003724 return GetElementsKind() == FAST_ELEMENTS;
3725}
3726
3727
3728bool JSObject::HasDictionaryElements() {
3729 return GetElementsKind() == DICTIONARY_ELEMENTS;
3730}
3731
3732
ager@chromium.org3811b432009-10-28 14:53:37 +00003733bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003734 HeapObject* array = elements();
3735 ASSERT(array != NULL);
3736 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00003737}
3738
3739
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003740#define EXTERNAL_ELEMENTS_CHECK(name, type) \
3741bool JSObject::HasExternal##name##Elements() { \
3742 HeapObject* array = elements(); \
3743 ASSERT(array != NULL); \
3744 if (!array->IsHeapObject()) \
3745 return false; \
3746 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00003747}
3748
3749
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003750EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
3751EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
3752EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
3753EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
3754 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
3755EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
3756EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
3757 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
3758EXTERNAL_ELEMENTS_CHECK(Float,
3759 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003760EXTERNAL_ELEMENTS_CHECK(Double,
3761 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003762EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00003763
3764
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003765bool JSObject::HasNamedInterceptor() {
3766 return map()->has_named_interceptor();
3767}
3768
3769
3770bool JSObject::HasIndexedInterceptor() {
3771 return map()->has_indexed_interceptor();
3772}
3773
3774
ager@chromium.org5c838252010-02-19 08:53:10 +00003775bool JSObject::AllowsSetElementsLength() {
3776 bool result = elements()->IsFixedArray();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003777 ASSERT(result == !HasExternalArrayElements());
ager@chromium.org5c838252010-02-19 08:53:10 +00003778 return result;
3779}
3780
3781
lrn@chromium.org303ada72010-10-27 09:33:13 +00003782MaybeObject* JSObject::EnsureWritableFastElements() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003783 ASSERT(HasFastElements());
3784 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003785 Isolate* isolate = GetIsolate();
3786 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003787 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003788 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
3789 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00003790 if (!maybe_writable_elems->ToObject(&writable_elems)) {
3791 return maybe_writable_elems;
3792 }
3793 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003794 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003795 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003796 return writable_elems;
3797}
3798
3799
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003800StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003801 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003802 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003803}
3804
3805
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003806NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003807 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003808 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003809}
3810
3811
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003812bool String::IsHashFieldComputed(uint32_t field) {
3813 return (field & kHashNotComputedMask) == 0;
3814}
3815
3816
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003817bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003818 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003819}
3820
3821
3822uint32_t String::Hash() {
3823 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003824 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003825 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003826 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003827 return ComputeAndSetHash();
3828}
3829
3830
ager@chromium.org7c537e22008-10-16 08:43:32 +00003831StringHasher::StringHasher(int length)
3832 : length_(length),
3833 raw_running_hash_(0),
3834 array_index_(0),
3835 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
3836 is_first_char_(true),
3837 is_valid_(true) { }
3838
3839
3840bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003841 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00003842}
3843
3844
3845void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003846 // Use the Jenkins one-at-a-time hash function to update the hash
3847 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003848 raw_running_hash_ += c;
3849 raw_running_hash_ += (raw_running_hash_ << 10);
3850 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003851 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003852 if (is_array_index_) {
3853 if (c < '0' || c > '9') {
3854 is_array_index_ = false;
3855 } else {
3856 int d = c - '0';
3857 if (is_first_char_) {
3858 is_first_char_ = false;
3859 if (c == '0' && length_ > 1) {
3860 is_array_index_ = false;
3861 return;
3862 }
3863 }
3864 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
3865 is_array_index_ = false;
3866 } else {
3867 array_index_ = array_index_ * 10 + d;
3868 }
3869 }
3870 }
3871}
3872
3873
3874void StringHasher::AddCharacterNoIndex(uc32 c) {
3875 ASSERT(!is_array_index());
3876 raw_running_hash_ += c;
3877 raw_running_hash_ += (raw_running_hash_ << 10);
3878 raw_running_hash_ ^= (raw_running_hash_ >> 6);
3879}
3880
3881
3882uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003883 // Get the calculated raw hash value and do some more bit ops to distribute
3884 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003885 uint32_t result = raw_running_hash_;
3886 result += (result << 3);
3887 result ^= (result >> 11);
3888 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003889 if (result == 0) {
3890 result = 27;
3891 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00003892 return result;
3893}
3894
3895
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003896template <typename schar>
3897uint32_t HashSequentialString(const schar* chars, int length) {
3898 StringHasher hasher(length);
3899 if (!hasher.has_trivial_hash()) {
3900 int i;
3901 for (i = 0; hasher.is_array_index() && (i < length); i++) {
3902 hasher.AddCharacter(chars[i]);
3903 }
3904 for (; i < length; i++) {
3905 hasher.AddCharacterNoIndex(chars[i]);
3906 }
3907 }
3908 return hasher.GetHashField();
3909}
3910
3911
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003912bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003913 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003914 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
3915 return false;
3916 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003917 return SlowAsArrayIndex(index);
3918}
3919
3920
3921Object* JSObject::GetPrototype() {
3922 return JSObject::cast(this)->map()->prototype();
3923}
3924
3925
3926PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
3927 return GetPropertyAttributeWithReceiver(this, key);
3928}
3929
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003930// TODO(504): this may be useful in other places too where JSGlobalProxy
3931// is used.
3932Object* JSObject::BypassGlobalProxy() {
3933 if (IsJSGlobalProxy()) {
3934 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003935 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003936 ASSERT(proto->IsJSGlobalObject());
3937 return proto;
3938 }
3939 return this;
3940}
3941
3942
3943bool JSObject::HasHiddenPropertiesObject() {
3944 ASSERT(!IsJSGlobalProxy());
3945 return GetPropertyAttributePostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003946 GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003947 false) != ABSENT;
3948}
3949
3950
3951Object* JSObject::GetHiddenPropertiesObject() {
3952 ASSERT(!IsJSGlobalProxy());
3953 PropertyAttributes attributes;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003954 // You can't install a getter on a property indexed by the hidden symbol,
3955 // so we can be sure that GetLocalPropertyPostInterceptor returns a real
3956 // object.
3957 Object* result =
3958 GetLocalPropertyPostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003959 GetHeap()->hidden_symbol(),
lrn@chromium.org303ada72010-10-27 09:33:13 +00003960 &attributes)->ToObjectUnchecked();
3961 return result;
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003962}
3963
3964
lrn@chromium.org303ada72010-10-27 09:33:13 +00003965MaybeObject* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003966 ASSERT(!IsJSGlobalProxy());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003967 return SetPropertyPostInterceptor(GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003968 hidden_obj,
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00003969 DONT_ENUM,
3970 kNonStrictMode);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003971}
3972
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003973
3974bool JSObject::HasElement(uint32_t index) {
3975 return HasElementWithReceiver(this, index);
3976}
3977
3978
3979bool AccessorInfo::all_can_read() {
3980 return BooleanBit::get(flag(), kAllCanReadBit);
3981}
3982
3983
3984void AccessorInfo::set_all_can_read(bool value) {
3985 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
3986}
3987
3988
3989bool AccessorInfo::all_can_write() {
3990 return BooleanBit::get(flag(), kAllCanWriteBit);
3991}
3992
3993
3994void AccessorInfo::set_all_can_write(bool value) {
3995 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
3996}
3997
3998
ager@chromium.org870a0b62008-11-04 11:43:05 +00003999bool AccessorInfo::prohibits_overwriting() {
4000 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4001}
4002
4003
4004void AccessorInfo::set_prohibits_overwriting(bool value) {
4005 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4006}
4007
4008
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004009PropertyAttributes AccessorInfo::property_attributes() {
4010 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4011}
4012
4013
4014void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
4015 ASSERT(AttributesField::is_valid(attributes));
4016 int rest_value = flag()->value() & ~AttributesField::mask();
4017 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
4018}
4019
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004020
4021template<typename Shape, typename Key>
4022void Dictionary<Shape, Key>::SetEntry(int entry,
4023 Object* key,
4024 Object* value) {
4025 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4026}
4027
4028
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004029template<typename Shape, typename Key>
4030void Dictionary<Shape, Key>::SetEntry(int entry,
4031 Object* key,
4032 Object* value,
4033 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004034 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004035 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004036 AssertNoAllocation no_gc;
4037 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004038 FixedArray::set(index, key, mode);
4039 FixedArray::set(index+1, value, mode);
4040 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004041}
4042
4043
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004044bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4045 ASSERT(other->IsNumber());
4046 return key == static_cast<uint32_t>(other->Number());
4047}
4048
4049
4050uint32_t NumberDictionaryShape::Hash(uint32_t key) {
4051 return ComputeIntegerHash(key);
4052}
4053
4054
4055uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
4056 ASSERT(other->IsNumber());
4057 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
4058}
4059
4060
4061MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4062 return Isolate::Current()->heap()->NumberFromUint32(key);
4063}
4064
4065
4066bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4067 // We know that all entries in a hash table had their hash keys created.
4068 // Use that knowledge to have fast failure.
4069 if (key->Hash() != String::cast(other)->Hash()) return false;
4070 return key->Equals(String::cast(other));
4071}
4072
4073
4074uint32_t StringDictionaryShape::Hash(String* key) {
4075 return key->Hash();
4076}
4077
4078
4079uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4080 return String::cast(other)->Hash();
4081}
4082
4083
4084MaybeObject* StringDictionaryShape::AsObject(String* key) {
4085 return key;
4086}
4087
4088
4089void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004090 // No write barrier is needed since empty_fixed_array is not in new space.
4091 // Please note this function is used during marking:
4092 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004093 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4094 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004095}
4096
4097
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004098void JSArray::EnsureSize(int required_size) {
4099 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004100 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004101 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4102 if (elts->length() < required_size) {
4103 // Doubling in size would be overkill, but leave some slack to avoid
4104 // constantly growing.
4105 Expand(required_size + (required_size >> 3));
4106 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004107 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004108 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4109 // Expand will allocate a new backing store in new space even if the size
4110 // we asked for isn't larger than what we had before.
4111 Expand(required_size);
4112 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004113}
4114
4115
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004116void JSArray::set_length(Smi* length) {
4117 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4118}
4119
4120
ager@chromium.org7c537e22008-10-16 08:43:32 +00004121void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004122 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004123 set_elements(storage);
4124}
4125
4126
lrn@chromium.org303ada72010-10-27 09:33:13 +00004127MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004128 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004129 return GetHeap()->CopyFixedArray(this);
4130}
4131
4132
4133Relocatable::Relocatable(Isolate* isolate) {
4134 ASSERT(isolate == Isolate::Current());
4135 isolate_ = isolate;
4136 prev_ = isolate->relocatable_top();
4137 isolate->set_relocatable_top(this);
4138}
4139
4140
4141Relocatable::~Relocatable() {
4142 ASSERT(isolate_ == Isolate::Current());
4143 ASSERT_EQ(isolate_->relocatable_top(), this);
4144 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004145}
4146
4147
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004148int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4149 return map->instance_size();
4150}
4151
4152
4153void Proxy::ProxyIterateBody(ObjectVisitor* v) {
4154 v->VisitExternalReference(
4155 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
4156}
4157
4158
4159template<typename StaticVisitor>
4160void Proxy::ProxyIterateBody() {
4161 StaticVisitor::VisitExternalReference(
4162 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
4163}
4164
4165
4166void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4167 typedef v8::String::ExternalAsciiStringResource Resource;
4168 v->VisitExternalAsciiString(
4169 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4170}
4171
4172
4173template<typename StaticVisitor>
4174void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4175 typedef v8::String::ExternalAsciiStringResource Resource;
4176 StaticVisitor::VisitExternalAsciiString(
4177 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4178}
4179
4180
4181void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4182 typedef v8::String::ExternalStringResource Resource;
4183 v->VisitExternalTwoByteString(
4184 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4185}
4186
4187
4188template<typename StaticVisitor>
4189void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4190 typedef v8::String::ExternalStringResource Resource;
4191 StaticVisitor::VisitExternalTwoByteString(
4192 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4193}
4194
4195#define SLOT_ADDR(obj, offset) \
4196 reinterpret_cast<Object**>((obj)->address() + offset)
4197
4198template<int start_offset, int end_offset, int size>
4199void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4200 HeapObject* obj,
4201 ObjectVisitor* v) {
4202 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4203}
4204
4205
4206template<int start_offset>
4207void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4208 int object_size,
4209 ObjectVisitor* v) {
4210 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4211}
4212
4213#undef SLOT_ADDR
4214
4215
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004216#undef CAST_ACCESSOR
4217#undef INT_ACCESSORS
4218#undef SMI_ACCESSORS
4219#undef ACCESSORS
4220#undef FIELD_ADDR
4221#undef READ_FIELD
4222#undef WRITE_FIELD
4223#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004224#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004225#undef READ_MEMADDR_FIELD
4226#undef WRITE_MEMADDR_FIELD
4227#undef READ_DOUBLE_FIELD
4228#undef WRITE_DOUBLE_FIELD
4229#undef READ_INT_FIELD
4230#undef WRITE_INT_FIELD
4231#undef READ_SHORT_FIELD
4232#undef WRITE_SHORT_FIELD
4233#undef READ_BYTE_FIELD
4234#undef WRITE_BYTE_FIELD
4235
4236
4237} } // namespace v8::internal
4238
4239#endif // V8_OBJECTS_INL_H_