blob: c8fcd02c5d04bcdc4c4d3806f717b85fa22f8906 [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
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000593bool Object::IsForeign() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000594 return Object::IsHeapObject()
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000595 && HeapObject::cast(this)->map()->instance_type() == FOREIGN_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() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00001677 ASSERT(this->IsSmi() ||
1678 this->length() > kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001679 this == HEAP->empty_descriptor_array());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001680 return this->IsSmi() || length() <= kFirstIndex;
1681}
1682
1683
1684int DescriptorArray::bit_field3_storage() {
1685 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1686 return Smi::cast(storage)->value();
1687}
1688
1689void DescriptorArray::set_bit_field3_storage(int value) {
1690 ASSERT(!IsEmpty());
1691 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001692}
1693
1694
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001695void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1696 Object* tmp = array->get(first);
1697 fast_set(array, first, array->get(second));
1698 fast_set(array, second, tmp);
1699}
1700
1701
1702int DescriptorArray::Search(String* name) {
1703 SLOW_ASSERT(IsSortedNoDuplicates());
1704
1705 // Check for empty descriptor array.
1706 int nof = number_of_descriptors();
1707 if (nof == 0) return kNotFound;
1708
1709 // Fast case: do linear search for small arrays.
1710 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001711 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001712 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001713 }
1714
1715 // Slow case: perform binary search.
1716 return BinarySearch(name, 0, nof - 1);
1717}
1718
1719
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001720int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001721 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001722 if (number == DescriptorLookupCache::kAbsent) {
1723 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001724 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001725 }
1726 return number;
1727}
1728
1729
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001730String* DescriptorArray::GetKey(int descriptor_number) {
1731 ASSERT(descriptor_number < number_of_descriptors());
1732 return String::cast(get(ToKeyIndex(descriptor_number)));
1733}
1734
1735
1736Object* DescriptorArray::GetValue(int descriptor_number) {
1737 ASSERT(descriptor_number < number_of_descriptors());
1738 return GetContentArray()->get(ToValueIndex(descriptor_number));
1739}
1740
1741
1742Smi* DescriptorArray::GetDetails(int descriptor_number) {
1743 ASSERT(descriptor_number < number_of_descriptors());
1744 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1745}
1746
1747
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001748PropertyType DescriptorArray::GetType(int descriptor_number) {
1749 ASSERT(descriptor_number < number_of_descriptors());
1750 return PropertyDetails(GetDetails(descriptor_number)).type();
1751}
1752
1753
1754int DescriptorArray::GetFieldIndex(int descriptor_number) {
1755 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1756}
1757
1758
1759JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1760 return JSFunction::cast(GetValue(descriptor_number));
1761}
1762
1763
1764Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1765 ASSERT(GetType(descriptor_number) == CALLBACKS);
1766 return GetValue(descriptor_number);
1767}
1768
1769
1770AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1771 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001772 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
1773 return reinterpret_cast<AccessorDescriptor*>(p->address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001774}
1775
1776
1777bool DescriptorArray::IsProperty(int descriptor_number) {
1778 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1779}
1780
1781
1782bool DescriptorArray::IsTransition(int descriptor_number) {
1783 PropertyType t = GetType(descriptor_number);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001784 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION ||
1785 t == EXTERNAL_ARRAY_TRANSITION;
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001786}
1787
1788
1789bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1790 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1791}
1792
1793
1794bool DescriptorArray::IsDontEnum(int descriptor_number) {
1795 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1796}
1797
1798
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001799void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1800 desc->Init(GetKey(descriptor_number),
1801 GetValue(descriptor_number),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001802 PropertyDetails(GetDetails(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001803}
1804
1805
1806void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1807 // Range check.
1808 ASSERT(descriptor_number < number_of_descriptors());
1809
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001810 // Make sure none of the elements in desc are in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001811 ASSERT(!HEAP->InNewSpace(desc->GetKey()));
1812 ASSERT(!HEAP->InNewSpace(desc->GetValue()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001813
1814 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1815 FixedArray* content_array = GetContentArray();
1816 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1817 fast_set(content_array, ToDetailsIndex(descriptor_number),
1818 desc->GetDetails().AsSmi());
1819}
1820
1821
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001822void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1823 Descriptor desc;
1824 src->Get(src_index, &desc);
1825 Set(index, &desc);
1826}
1827
1828
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001829void DescriptorArray::Swap(int first, int second) {
1830 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1831 FixedArray* content_array = GetContentArray();
1832 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1833 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1834}
1835
1836
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001837template<typename Shape, typename Key>
1838int HashTable<Shape, Key>::FindEntry(Key key) {
1839 return FindEntry(GetIsolate(), key);
1840}
1841
1842
1843// Find entry for key otherwise return kNotFound.
1844template<typename Shape, typename Key>
1845int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
1846 uint32_t capacity = Capacity();
1847 uint32_t entry = FirstProbe(Shape::Hash(key), capacity);
1848 uint32_t count = 1;
1849 // EnsureCapacity will guarantee the hash table is never full.
1850 while (true) {
1851 Object* element = KeyAt(entry);
1852 if (element == isolate->heap()->undefined_value()) break; // Empty entry.
1853 if (element != isolate->heap()->null_value() &&
1854 Shape::IsMatch(key, element)) return entry;
1855 entry = NextProbe(entry, count++, capacity);
1856 }
1857 return kNotFound;
1858}
1859
1860
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001861bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001862 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001863 if (!max_index_object->IsSmi()) return false;
1864 return 0 !=
1865 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1866}
1867
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001868uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001869 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001870 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001871 if (!max_index_object->IsSmi()) return 0;
1872 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1873 return value >> kRequiresSlowElementsTagSize;
1874}
1875
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001876void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001877 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001878}
1879
1880
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001881// ------------------------------------
1882// Cast operations
1883
1884
1885CAST_ACCESSOR(FixedArray)
1886CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001887CAST_ACCESSOR(DeoptimizationInputData)
1888CAST_ACCESSOR(DeoptimizationOutputData)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001889CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00001890CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00001891CAST_ACCESSOR(NormalizedMapCache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00001892CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001893CAST_ACCESSOR(CodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00001894CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001895CAST_ACCESSOR(String)
1896CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00001897CAST_ACCESSOR(SeqAsciiString)
1898CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001899CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001900CAST_ACCESSOR(ExternalString)
1901CAST_ACCESSOR(ExternalAsciiString)
1902CAST_ACCESSOR(ExternalTwoByteString)
1903CAST_ACCESSOR(JSObject)
1904CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001905CAST_ACCESSOR(HeapObject)
1906CAST_ACCESSOR(HeapNumber)
1907CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001908CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001909CAST_ACCESSOR(SharedFunctionInfo)
1910CAST_ACCESSOR(Map)
1911CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001912CAST_ACCESSOR(GlobalObject)
1913CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001914CAST_ACCESSOR(JSGlobalObject)
1915CAST_ACCESSOR(JSBuiltinsObject)
1916CAST_ACCESSOR(Code)
1917CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00001918CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00001919CAST_ACCESSOR(JSProxy)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001920CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001921CAST_ACCESSOR(ByteArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00001922CAST_ACCESSOR(ExternalArray)
1923CAST_ACCESSOR(ExternalByteArray)
1924CAST_ACCESSOR(ExternalUnsignedByteArray)
1925CAST_ACCESSOR(ExternalShortArray)
1926CAST_ACCESSOR(ExternalUnsignedShortArray)
1927CAST_ACCESSOR(ExternalIntArray)
1928CAST_ACCESSOR(ExternalUnsignedIntArray)
1929CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00001930CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001931CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001932CAST_ACCESSOR(Struct)
1933
1934
1935#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
1936 STRUCT_LIST(MAKE_STRUCT_CAST)
1937#undef MAKE_STRUCT_CAST
1938
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001939
1940template <typename Shape, typename Key>
1941HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001942 ASSERT(obj->IsHashTable());
1943 return reinterpret_cast<HashTable*>(obj);
1944}
1945
1946
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001947SMI_ACCESSORS(FixedArray, length, kLengthOffset)
1948SMI_ACCESSORS(ByteArray, length, kLengthOffset)
1949
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001950INT_ACCESSORS(ExternalArray, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001951
1952
ager@chromium.orgac091b72010-05-05 07:34:42 +00001953SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001954
1955
1956uint32_t String::hash_field() {
1957 return READ_UINT32_FIELD(this, kHashFieldOffset);
1958}
1959
1960
1961void String::set_hash_field(uint32_t value) {
1962 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001963#if V8_HOST_ARCH_64_BIT
1964 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
1965#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001966}
1967
1968
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001969bool String::Equals(String* other) {
1970 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001971 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
1972 return false;
1973 }
1974 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001975}
1976
1977
lrn@chromium.org303ada72010-10-27 09:33:13 +00001978MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001979 if (!StringShape(this).IsCons()) return this;
1980 ConsString* cons = ConsString::cast(this);
1981 if (cons->second()->length() == 0) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001982 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001983}
1984
1985
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001986String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00001987 MaybeObject* flat = TryFlatten(pretenure);
1988 Object* successfully_flattened;
1989 if (flat->ToObject(&successfully_flattened)) {
1990 return String::cast(successfully_flattened);
1991 }
1992 return this;
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001993}
1994
1995
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001996uint16_t String::Get(int index) {
1997 ASSERT(index >= 0 && index < length());
1998 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001999 case kSeqStringTag | kAsciiStringTag:
2000 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2001 case kSeqStringTag | kTwoByteStringTag:
2002 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2003 case kConsStringTag | kAsciiStringTag:
2004 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002005 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002006 case kExternalStringTag | kAsciiStringTag:
2007 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2008 case kExternalStringTag | kTwoByteStringTag:
2009 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002010 default:
2011 break;
2012 }
2013
2014 UNREACHABLE();
2015 return 0;
2016}
2017
2018
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002019void String::Set(int index, uint16_t value) {
2020 ASSERT(index >= 0 && index < length());
2021 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002022
ager@chromium.org5ec48922009-05-05 07:25:34 +00002023 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002024 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2025 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002026}
2027
2028
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002029bool String::IsFlat() {
2030 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002031 case kConsStringTag: {
2032 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00002033 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00002034 return second->length() == 0;
2035 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00002036 default:
2037 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002038 }
2039}
2040
2041
ager@chromium.org7c537e22008-10-16 08:43:32 +00002042uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002043 ASSERT(index >= 0 && index < length());
2044 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2045}
2046
2047
ager@chromium.org7c537e22008-10-16 08:43:32 +00002048void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002049 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2050 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2051 static_cast<byte>(value));
2052}
2053
2054
ager@chromium.org7c537e22008-10-16 08:43:32 +00002055Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002056 return FIELD_ADDR(this, kHeaderSize);
2057}
2058
2059
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002060char* SeqAsciiString::GetChars() {
2061 return reinterpret_cast<char*>(GetCharsAddress());
2062}
2063
2064
ager@chromium.org7c537e22008-10-16 08:43:32 +00002065Address SeqTwoByteString::GetCharsAddress() {
2066 return FIELD_ADDR(this, kHeaderSize);
2067}
2068
2069
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002070uc16* SeqTwoByteString::GetChars() {
2071 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2072}
2073
2074
ager@chromium.org7c537e22008-10-16 08:43:32 +00002075uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002076 ASSERT(index >= 0 && index < length());
2077 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2078}
2079
2080
ager@chromium.org7c537e22008-10-16 08:43:32 +00002081void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002082 ASSERT(index >= 0 && index < length());
2083 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2084}
2085
2086
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002087int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002088 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002089}
2090
2091
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002092int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002093 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002094}
2095
2096
ager@chromium.org870a0b62008-11-04 11:43:05 +00002097String* ConsString::first() {
2098 return String::cast(READ_FIELD(this, kFirstOffset));
2099}
2100
2101
2102Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002103 return READ_FIELD(this, kFirstOffset);
2104}
2105
2106
ager@chromium.org870a0b62008-11-04 11:43:05 +00002107void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002108 WRITE_FIELD(this, kFirstOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002109 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002110}
2111
2112
ager@chromium.org870a0b62008-11-04 11:43:05 +00002113String* ConsString::second() {
2114 return String::cast(READ_FIELD(this, kSecondOffset));
2115}
2116
2117
2118Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002119 return READ_FIELD(this, kSecondOffset);
2120}
2121
2122
ager@chromium.org870a0b62008-11-04 11:43:05 +00002123void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002124 WRITE_FIELD(this, kSecondOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002125 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002126}
2127
2128
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002129ExternalAsciiString::Resource* ExternalAsciiString::resource() {
2130 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2131}
2132
2133
2134void ExternalAsciiString::set_resource(
2135 ExternalAsciiString::Resource* resource) {
2136 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2137}
2138
2139
2140ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
2141 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2142}
2143
2144
2145void ExternalTwoByteString::set_resource(
2146 ExternalTwoByteString::Resource* resource) {
2147 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2148}
2149
2150
ager@chromium.orgac091b72010-05-05 07:34:42 +00002151void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002152 set_finger_index(kEntriesIndex);
2153 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002154}
2155
2156
2157void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002158 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002159 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002160 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002161 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002162 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002163 MakeZeroSize();
2164}
2165
2166
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002167int JSFunctionResultCache::size() {
2168 return Smi::cast(get(kCacheSizeIndex))->value();
2169}
2170
2171
2172void JSFunctionResultCache::set_size(int size) {
2173 set(kCacheSizeIndex, Smi::FromInt(size));
2174}
2175
2176
2177int JSFunctionResultCache::finger_index() {
2178 return Smi::cast(get(kFingerIndex))->value();
2179}
2180
2181
2182void JSFunctionResultCache::set_finger_index(int finger_index) {
2183 set(kFingerIndex, Smi::FromInt(finger_index));
2184}
2185
2186
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002187byte ByteArray::get(int index) {
2188 ASSERT(index >= 0 && index < this->length());
2189 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2190}
2191
2192
2193void ByteArray::set(int index, byte value) {
2194 ASSERT(index >= 0 && index < this->length());
2195 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2196}
2197
2198
2199int ByteArray::get_int(int index) {
2200 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2201 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2202}
2203
2204
2205ByteArray* ByteArray::FromDataStartAddress(Address address) {
2206 ASSERT_TAG_ALIGNED(address);
2207 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2208}
2209
2210
2211Address ByteArray::GetDataStartAddress() {
2212 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2213}
2214
2215
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002216uint8_t* ExternalPixelArray::external_pixel_pointer() {
2217 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002218}
2219
2220
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002221uint8_t ExternalPixelArray::get(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002222 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002223 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002224 return ptr[index];
2225}
2226
2227
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002228void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002229 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002230 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002231 ptr[index] = value;
2232}
2233
2234
ager@chromium.org3811b432009-10-28 14:53:37 +00002235void* ExternalArray::external_pointer() {
2236 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2237 return reinterpret_cast<void*>(ptr);
2238}
2239
2240
2241void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2242 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2243 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2244}
2245
2246
2247int8_t ExternalByteArray::get(int index) {
2248 ASSERT((index >= 0) && (index < this->length()));
2249 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2250 return ptr[index];
2251}
2252
2253
2254void ExternalByteArray::set(int index, int8_t value) {
2255 ASSERT((index >= 0) && (index < this->length()));
2256 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2257 ptr[index] = value;
2258}
2259
2260
2261uint8_t ExternalUnsignedByteArray::get(int index) {
2262 ASSERT((index >= 0) && (index < this->length()));
2263 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2264 return ptr[index];
2265}
2266
2267
2268void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2269 ASSERT((index >= 0) && (index < this->length()));
2270 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2271 ptr[index] = value;
2272}
2273
2274
2275int16_t ExternalShortArray::get(int index) {
2276 ASSERT((index >= 0) && (index < this->length()));
2277 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2278 return ptr[index];
2279}
2280
2281
2282void ExternalShortArray::set(int index, int16_t value) {
2283 ASSERT((index >= 0) && (index < this->length()));
2284 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2285 ptr[index] = value;
2286}
2287
2288
2289uint16_t ExternalUnsignedShortArray::get(int index) {
2290 ASSERT((index >= 0) && (index < this->length()));
2291 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2292 return ptr[index];
2293}
2294
2295
2296void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2297 ASSERT((index >= 0) && (index < this->length()));
2298 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2299 ptr[index] = value;
2300}
2301
2302
2303int32_t ExternalIntArray::get(int index) {
2304 ASSERT((index >= 0) && (index < this->length()));
2305 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2306 return ptr[index];
2307}
2308
2309
2310void ExternalIntArray::set(int index, int32_t value) {
2311 ASSERT((index >= 0) && (index < this->length()));
2312 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2313 ptr[index] = value;
2314}
2315
2316
2317uint32_t ExternalUnsignedIntArray::get(int index) {
2318 ASSERT((index >= 0) && (index < this->length()));
2319 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2320 return ptr[index];
2321}
2322
2323
2324void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2325 ASSERT((index >= 0) && (index < this->length()));
2326 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2327 ptr[index] = value;
2328}
2329
2330
2331float ExternalFloatArray::get(int index) {
2332 ASSERT((index >= 0) && (index < this->length()));
2333 float* ptr = static_cast<float*>(external_pointer());
2334 return ptr[index];
2335}
2336
2337
2338void ExternalFloatArray::set(int index, float value) {
2339 ASSERT((index >= 0) && (index < this->length()));
2340 float* ptr = static_cast<float*>(external_pointer());
2341 ptr[index] = value;
2342}
2343
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002344
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002345double ExternalDoubleArray::get(int index) {
2346 ASSERT((index >= 0) && (index < this->length()));
2347 double* ptr = static_cast<double*>(external_pointer());
2348 return ptr[index];
2349}
2350
2351
2352void ExternalDoubleArray::set(int index, double value) {
2353 ASSERT((index >= 0) && (index < this->length()));
2354 double* ptr = static_cast<double*>(external_pointer());
2355 ptr[index] = value;
2356}
2357
2358
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002359int Map::visitor_id() {
2360 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2361}
2362
2363
2364void Map::set_visitor_id(int id) {
2365 ASSERT(0 <= id && id < 256);
2366 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2367}
2368
ager@chromium.org3811b432009-10-28 14:53:37 +00002369
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002370int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002371 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2372}
2373
2374
2375int Map::inobject_properties() {
2376 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002377}
2378
2379
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002380int Map::pre_allocated_property_fields() {
2381 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2382}
2383
2384
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002385int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002386 int instance_size = map->instance_size();
2387 if (instance_size != kVariableSizeSentinel) return instance_size;
2388 // We can ignore the "symbol" bit becase it is only set for symbols
2389 // and implies a string type.
2390 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002391 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002392 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002393 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002394 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002395 if (instance_type == ASCII_STRING_TYPE) {
2396 return SeqAsciiString::SizeFor(
2397 reinterpret_cast<SeqAsciiString*>(this)->length());
2398 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002399 if (instance_type == BYTE_ARRAY_TYPE) {
2400 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2401 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002402 if (instance_type == STRING_TYPE) {
2403 return SeqTwoByteString::SizeFor(
2404 reinterpret_cast<SeqTwoByteString*>(this)->length());
2405 }
2406 ASSERT(instance_type == CODE_TYPE);
2407 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002408}
2409
2410
2411void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002412 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002413 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002414 ASSERT(0 <= value && value < 256);
2415 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2416}
2417
2418
ager@chromium.org7c537e22008-10-16 08:43:32 +00002419void Map::set_inobject_properties(int value) {
2420 ASSERT(0 <= value && value < 256);
2421 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2422}
2423
2424
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002425void Map::set_pre_allocated_property_fields(int value) {
2426 ASSERT(0 <= value && value < 256);
2427 WRITE_BYTE_FIELD(this,
2428 kPreAllocatedPropertyFieldsOffset,
2429 static_cast<byte>(value));
2430}
2431
2432
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002433InstanceType Map::instance_type() {
2434 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2435}
2436
2437
2438void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002439 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2440}
2441
2442
2443int Map::unused_property_fields() {
2444 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2445}
2446
2447
2448void Map::set_unused_property_fields(int value) {
2449 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2450}
2451
2452
2453byte Map::bit_field() {
2454 return READ_BYTE_FIELD(this, kBitFieldOffset);
2455}
2456
2457
2458void Map::set_bit_field(byte value) {
2459 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2460}
2461
2462
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002463byte Map::bit_field2() {
2464 return READ_BYTE_FIELD(this, kBitField2Offset);
2465}
2466
2467
2468void Map::set_bit_field2(byte value) {
2469 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2470}
2471
2472
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002473void Map::set_non_instance_prototype(bool value) {
2474 if (value) {
2475 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2476 } else {
2477 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2478 }
2479}
2480
2481
2482bool Map::has_non_instance_prototype() {
2483 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2484}
2485
2486
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002487void Map::set_function_with_prototype(bool value) {
2488 if (value) {
2489 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2490 } else {
2491 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2492 }
2493}
2494
2495
2496bool Map::function_with_prototype() {
2497 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2498}
2499
2500
ager@chromium.org870a0b62008-11-04 11:43:05 +00002501void Map::set_is_access_check_needed(bool access_check_needed) {
2502 if (access_check_needed) {
2503 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2504 } else {
2505 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2506 }
2507}
2508
2509
2510bool Map::is_access_check_needed() {
2511 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2512}
2513
2514
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002515void Map::set_is_extensible(bool value) {
2516 if (value) {
2517 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2518 } else {
2519 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2520 }
2521}
2522
2523bool Map::is_extensible() {
2524 return ((1 << kIsExtensible) & bit_field2()) != 0;
2525}
2526
2527
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002528void Map::set_attached_to_shared_function_info(bool value) {
2529 if (value) {
2530 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2531 } else {
2532 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2533 }
2534}
2535
2536bool Map::attached_to_shared_function_info() {
2537 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2538}
2539
2540
2541void Map::set_is_shared(bool value) {
2542 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002543 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002544 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002545 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002546 }
2547}
2548
2549bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002550 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002551}
2552
2553
2554JSFunction* Map::unchecked_constructor() {
2555 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2556}
2557
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002558
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002559FixedArray* Map::unchecked_prototype_transitions() {
2560 return reinterpret_cast<FixedArray*>(
2561 READ_FIELD(this, kPrototypeTransitionsOffset));
2562}
2563
2564
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002565Code::Flags Code::flags() {
2566 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2567}
2568
2569
2570void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002571 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002572 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002573 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2574 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002575 ExtractArgumentsCountFromFlags(flags) >= 0);
2576 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2577}
2578
2579
2580Code::Kind Code::kind() {
2581 return ExtractKindFromFlags(flags());
2582}
2583
2584
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002585InLoopFlag Code::ic_in_loop() {
2586 return ExtractICInLoopFromFlags(flags());
2587}
2588
2589
kasper.lund7276f142008-07-30 08:49:36 +00002590InlineCacheState Code::ic_state() {
2591 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002592 // Only allow uninitialized or debugger states for non-IC code
2593 // objects. This is used in the debugger to determine whether or not
2594 // a call to code object has been replaced with a debug break call.
2595 ASSERT(is_inline_cache_stub() ||
2596 result == UNINITIALIZED ||
2597 result == DEBUG_BREAK ||
2598 result == DEBUG_PREPARE_STEP_IN);
2599 return result;
2600}
2601
2602
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002603Code::ExtraICState Code::extra_ic_state() {
2604 ASSERT(is_inline_cache_stub());
2605 return ExtractExtraICStateFromFlags(flags());
2606}
2607
2608
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002609PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002610 return ExtractTypeFromFlags(flags());
2611}
2612
2613
2614int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002615 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002616 return ExtractArgumentsCountFromFlags(flags());
2617}
2618
2619
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002620int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002621 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002622 kind() == UNARY_OP_IC ||
2623 kind() == BINARY_OP_IC ||
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002624 kind() == COMPARE_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002625 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002626}
2627
2628
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002629void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002630 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002631 kind() == UNARY_OP_IC ||
2632 kind() == BINARY_OP_IC ||
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002633 kind() == COMPARE_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002634 ASSERT(0 <= major && major < 256);
2635 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002636}
2637
2638
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002639bool Code::optimizable() {
2640 ASSERT(kind() == FUNCTION);
2641 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2642}
2643
2644
2645void Code::set_optimizable(bool value) {
2646 ASSERT(kind() == FUNCTION);
2647 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2648}
2649
2650
2651bool Code::has_deoptimization_support() {
2652 ASSERT(kind() == FUNCTION);
2653 return READ_BYTE_FIELD(this, kHasDeoptimizationSupportOffset) == 1;
2654}
2655
2656
2657void Code::set_has_deoptimization_support(bool value) {
2658 ASSERT(kind() == FUNCTION);
2659 WRITE_BYTE_FIELD(this, kHasDeoptimizationSupportOffset, value ? 1 : 0);
2660}
2661
2662
2663int Code::allow_osr_at_loop_nesting_level() {
2664 ASSERT(kind() == FUNCTION);
2665 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
2666}
2667
2668
2669void Code::set_allow_osr_at_loop_nesting_level(int level) {
2670 ASSERT(kind() == FUNCTION);
2671 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
2672 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
2673}
2674
2675
2676unsigned Code::stack_slots() {
2677 ASSERT(kind() == OPTIMIZED_FUNCTION);
2678 return READ_UINT32_FIELD(this, kStackSlotsOffset);
2679}
2680
2681
2682void Code::set_stack_slots(unsigned slots) {
2683 ASSERT(kind() == OPTIMIZED_FUNCTION);
2684 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
2685}
2686
2687
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002688unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002689 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002690 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002691}
2692
2693
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002694void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002695 ASSERT(kind() == OPTIMIZED_FUNCTION);
2696 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002697 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002698}
2699
2700
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002701unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002702 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002703 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002704}
2705
2706
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002707void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002708 ASSERT(kind() == FUNCTION);
2709 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002710 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002711}
2712
2713
2714CheckType Code::check_type() {
2715 ASSERT(is_call_stub() || is_keyed_call_stub());
2716 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
2717 return static_cast<CheckType>(type);
2718}
2719
2720
2721void Code::set_check_type(CheckType value) {
2722 ASSERT(is_call_stub() || is_keyed_call_stub());
2723 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
2724}
2725
2726
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002727ExternalArrayType Code::external_array_type() {
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002728 ASSERT(is_keyed_load_stub() || is_keyed_store_stub());
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002729 byte type = READ_BYTE_FIELD(this, kExternalArrayTypeOffset);
2730 return static_cast<ExternalArrayType>(type);
2731}
2732
2733
2734void Code::set_external_array_type(ExternalArrayType value) {
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002735 ASSERT(is_keyed_load_stub() || is_keyed_store_stub());
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002736 WRITE_BYTE_FIELD(this, kExternalArrayTypeOffset, value);
2737}
2738
2739
danno@chromium.org40cb8782011-05-25 07:58:50 +00002740byte Code::unary_op_type() {
2741 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002742 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
2743}
2744
2745
danno@chromium.org40cb8782011-05-25 07:58:50 +00002746void Code::set_unary_op_type(byte value) {
2747 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002748 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
2749}
2750
2751
danno@chromium.org40cb8782011-05-25 07:58:50 +00002752byte Code::binary_op_type() {
2753 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002754 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
2755}
2756
2757
danno@chromium.org40cb8782011-05-25 07:58:50 +00002758void Code::set_binary_op_type(byte value) {
2759 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002760 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
2761}
2762
2763
danno@chromium.org40cb8782011-05-25 07:58:50 +00002764byte Code::binary_op_result_type() {
2765 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002766 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
2767}
2768
2769
danno@chromium.org40cb8782011-05-25 07:58:50 +00002770void Code::set_binary_op_result_type(byte value) {
2771 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002772 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
2773}
2774
2775
2776byte Code::compare_state() {
2777 ASSERT(is_compare_ic_stub());
2778 return READ_BYTE_FIELD(this, kCompareStateOffset);
2779}
2780
2781
2782void Code::set_compare_state(byte value) {
2783 ASSERT(is_compare_ic_stub());
2784 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
2785}
2786
2787
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002788bool Code::is_inline_cache_stub() {
2789 Kind kind = this->kind();
2790 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2791}
2792
2793
2794Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002795 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002796 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002797 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002798 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002799 int argc,
2800 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002801 // Extra IC state is only allowed for call IC stubs or for store IC
2802 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002803 ASSERT(extra_ic_state == kNoExtraICState ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002804 (kind == CALL_IC) ||
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00002805 (kind == STORE_IC) ||
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002806 (kind == KEYED_STORE_IC));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002807 // Compute the bit mask.
2808 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002809 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002810 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002811 bits |= type << kFlagsTypeShift;
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002812 bits |= extra_ic_state << kFlagsExtraICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002813 bits |= argc << kFlagsArgumentsCountShift;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002814 if (holder == PROTOTYPE_MAP) bits |= kFlagsCacheInPrototypeMapMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002815 // Cast to flags and validate result before returning it.
2816 Flags result = static_cast<Flags>(bits);
2817 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002818 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002819 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002820 ASSERT(ExtractTypeFromFlags(result) == type);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002821 ASSERT(ExtractExtraICStateFromFlags(result) == extra_ic_state);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002822 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2823 return result;
2824}
2825
2826
2827Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2828 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002829 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002830 InlineCacheHolderFlag holder,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002831 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002832 int argc) {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002833 return ComputeFlags(
2834 kind, in_loop, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002835}
2836
2837
2838Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2839 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2840 return static_cast<Kind>(bits);
2841}
2842
2843
kasper.lund7276f142008-07-30 08:49:36 +00002844InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2845 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002846 return static_cast<InlineCacheState>(bits);
2847}
2848
2849
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002850Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
2851 int bits = (flags & kFlagsExtraICStateMask) >> kFlagsExtraICStateShift;
2852 return static_cast<ExtraICState>(bits);
2853}
2854
2855
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002856InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2857 int bits = (flags & kFlagsICInLoopMask);
2858 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2859}
2860
2861
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002862PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2863 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2864 return static_cast<PropertyType>(bits);
2865}
2866
2867
2868int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2869 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2870}
2871
2872
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002873InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
2874 int bits = (flags & kFlagsCacheInPrototypeMapMask);
2875 return bits != 0 ? PROTOTYPE_MAP : OWN_MAP;
2876}
2877
2878
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002879Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2880 int bits = flags & ~kFlagsTypeMask;
2881 return static_cast<Flags>(bits);
2882}
2883
2884
ager@chromium.org8bb60582008-12-11 12:02:20 +00002885Code* Code::GetCodeFromTargetAddress(Address address) {
2886 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2887 // GetCodeFromTargetAddress might be called when marking objects during mark
2888 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2889 // Code::cast. Code::cast does not work when the object's map is
2890 // marked.
2891 Code* result = reinterpret_cast<Code*>(code);
2892 return result;
2893}
2894
2895
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002896Isolate* Map::isolate() {
2897 return heap()->isolate();
2898}
2899
2900
2901Heap* Map::heap() {
2902 // NOTE: address() helper is not used to save one instruction.
2903 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
2904 ASSERT(heap != NULL);
2905 ASSERT(heap->isolate() == Isolate::Current());
2906 return heap;
2907}
2908
2909
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002910Heap* Code::heap() {
2911 // NOTE: address() helper is not used to save one instruction.
2912 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
2913 ASSERT(heap != NULL);
2914 ASSERT(heap->isolate() == Isolate::Current());
2915 return heap;
2916}
2917
2918
2919Isolate* Code::isolate() {
2920 return heap()->isolate();
2921}
2922
2923
2924Heap* JSGlobalPropertyCell::heap() {
2925 // NOTE: address() helper is not used to save one instruction.
2926 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
2927 ASSERT(heap != NULL);
2928 ASSERT(heap->isolate() == Isolate::Current());
2929 return heap;
2930}
2931
2932
2933Isolate* JSGlobalPropertyCell::isolate() {
2934 return heap()->isolate();
2935}
2936
2937
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002938Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
2939 return HeapObject::
2940 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
2941}
2942
2943
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002944Object* Map::prototype() {
2945 return READ_FIELD(this, kPrototypeOffset);
2946}
2947
2948
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002949void Map::set_prototype(Object* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002950 ASSERT(value->IsNull() || value->IsJSObject());
2951 WRITE_FIELD(this, kPrototypeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002952 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002953}
2954
2955
lrn@chromium.org303ada72010-10-27 09:33:13 +00002956MaybeObject* Map::GetFastElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002957 if (has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00002958 Object* obj;
2959 { MaybeObject* maybe_obj = CopyDropTransitions();
2960 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2961 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002962 Map* new_map = Map::cast(obj);
2963 new_map->set_has_fast_elements(true);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002964 isolate()->counters()->map_slow_to_fast_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002965 return new_map;
2966}
2967
2968
lrn@chromium.org303ada72010-10-27 09:33:13 +00002969MaybeObject* Map::GetSlowElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002970 if (!has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00002971 Object* obj;
2972 { MaybeObject* maybe_obj = CopyDropTransitions();
2973 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2974 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002975 Map* new_map = Map::cast(obj);
2976 new_map->set_has_fast_elements(false);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002977 isolate()->counters()->map_fast_to_slow_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002978 return new_map;
2979}
2980
2981
danno@chromium.org40cb8782011-05-25 07:58:50 +00002982DescriptorArray* Map::instance_descriptors() {
2983 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
2984 if (object->IsSmi()) {
2985 return HEAP->empty_descriptor_array();
2986 } else {
2987 return DescriptorArray::cast(object);
2988 }
2989}
2990
2991
2992void Map::init_instance_descriptors() {
2993 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
2994}
2995
2996
2997void Map::clear_instance_descriptors() {
2998 Object* object = READ_FIELD(this,
2999 kInstanceDescriptorsOrBitField3Offset);
3000 if (!object->IsSmi()) {
3001 WRITE_FIELD(
3002 this,
3003 kInstanceDescriptorsOrBitField3Offset,
3004 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3005 }
3006}
3007
3008
3009void Map::set_instance_descriptors(DescriptorArray* value,
3010 WriteBarrierMode mode) {
3011 Object* object = READ_FIELD(this,
3012 kInstanceDescriptorsOrBitField3Offset);
3013 if (value == isolate()->heap()->empty_descriptor_array()) {
3014 clear_instance_descriptors();
3015 return;
3016 } else {
3017 if (object->IsSmi()) {
3018 value->set_bit_field3_storage(Smi::cast(object)->value());
3019 } else {
3020 value->set_bit_field3_storage(
3021 DescriptorArray::cast(object)->bit_field3_storage());
3022 }
3023 }
3024 ASSERT(!is_shared());
3025 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
3026 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3027 this,
3028 kInstanceDescriptorsOrBitField3Offset,
3029 mode);
3030}
3031
3032
3033int Map::bit_field3() {
3034 Object* object = READ_FIELD(this,
3035 kInstanceDescriptorsOrBitField3Offset);
3036 if (object->IsSmi()) {
3037 return Smi::cast(object)->value();
3038 } else {
3039 return DescriptorArray::cast(object)->bit_field3_storage();
3040 }
3041}
3042
3043
3044void Map::set_bit_field3(int value) {
3045 ASSERT(Smi::IsValid(value));
3046 Object* object = READ_FIELD(this,
3047 kInstanceDescriptorsOrBitField3Offset);
3048 if (object->IsSmi()) {
3049 WRITE_FIELD(this,
3050 kInstanceDescriptorsOrBitField3Offset,
3051 Smi::FromInt(value));
3052 } else {
3053 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3054 }
3055}
3056
3057
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003058ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003059ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003060ACCESSORS(Map, constructor, Object, kConstructorOffset)
3061
3062ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
3063ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003064ACCESSORS_GCSAFE(JSFunction, next_function_link, Object,
3065 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003066
3067ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3068ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003069ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003070
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003071ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003072
3073ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3074ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3075ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3076ACCESSORS(AccessorInfo, name, Object, kNameOffset)
3077ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
3078
3079ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3080ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3081ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3082
3083ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3084ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3085ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3086ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3087ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3088ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3089
3090ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3091ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3092
3093ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3094ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3095
3096ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3097ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003098ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3099 kPropertyAccessorsOffset)
3100ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3101 kPrototypeTemplateOffset)
3102ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3103ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3104 kNamedPropertyHandlerOffset)
3105ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3106 kIndexedPropertyHandlerOffset)
3107ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3108 kInstanceTemplateOffset)
3109ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3110ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003111ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3112 kInstanceCallHandlerOffset)
3113ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3114 kAccessCheckInfoOffset)
3115ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
3116
3117ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003118ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3119 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003120
3121ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3122ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3123
3124ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3125
3126ACCESSORS(Script, source, Object, kSourceOffset)
3127ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003128ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003129ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3130ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003131ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003132ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003133ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003134ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003135ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003136ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003137ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003138ACCESSORS(Script, eval_from_instructions_offset, Smi,
3139 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003140
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003141#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003142ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3143ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3144ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3145ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3146
3147ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3148ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3149ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3150ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003151#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003152
3153ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003154ACCESSORS_GCSAFE(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3155ACCESSORS_GCSAFE(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003156ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3157 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003158ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003159ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3160ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003161ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003162ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3163 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003164
3165BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3166 kHiddenPrototypeBit)
3167BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3168BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3169 kNeedsAccessCheckBit)
3170BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3171 kIsExpressionBit)
3172BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3173 kIsTopLevelBit)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003174BOOL_GETTER(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003175 has_only_simple_this_property_assignments,
3176 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003177BOOL_ACCESSORS(SharedFunctionInfo,
3178 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003179 allows_lazy_compilation,
3180 kAllowLazyCompilation)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003181
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003182
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003183#if V8_HOST_ARCH_32_BIT
3184SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3185SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003186 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003187SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003188 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003189SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3190SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003191 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003192SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3193SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003194 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003195SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003196 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003197SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003198 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003199SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003200#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003201
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003202#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003203 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003204 int holder::name() { \
3205 int value = READ_INT_FIELD(this, offset); \
3206 ASSERT(kHeapObjectTag == 1); \
3207 ASSERT((value & kHeapObjectTag) == 0); \
3208 return value >> 1; \
3209 } \
3210 void holder::set_##name(int value) { \
3211 ASSERT(kHeapObjectTag == 1); \
3212 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3213 (value & 0xC0000000) == 0x000000000); \
3214 WRITE_INT_FIELD(this, \
3215 offset, \
3216 (value << 1) & ~kHeapObjectTag); \
3217 }
3218
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003219#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3220 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003221 INT_ACCESSORS(holder, name, offset)
3222
3223
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003224PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003225PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3226 formal_parameter_count,
3227 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003228
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003229PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3230 expected_nof_properties,
3231 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003232PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3233
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003234PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3235PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3236 start_position_and_type,
3237 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003238
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003239PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3240 function_token_position,
3241 kFunctionTokenPositionOffset)
3242PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3243 compiler_hints,
3244 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003245
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003246PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3247 this_property_assignments_count,
3248 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003249PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003250#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003251
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003252
3253int SharedFunctionInfo::construction_count() {
3254 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3255}
3256
3257
3258void SharedFunctionInfo::set_construction_count(int value) {
3259 ASSERT(0 <= value && value < 256);
3260 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3261}
3262
3263
3264bool SharedFunctionInfo::live_objects_may_exist() {
3265 return (compiler_hints() & (1 << kLiveObjectsMayExist)) != 0;
3266}
3267
3268
3269void SharedFunctionInfo::set_live_objects_may_exist(bool value) {
3270 if (value) {
3271 set_compiler_hints(compiler_hints() | (1 << kLiveObjectsMayExist));
3272 } else {
3273 set_compiler_hints(compiler_hints() & ~(1 << kLiveObjectsMayExist));
3274 }
3275}
3276
3277
3278bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003279 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003280}
3281
3282
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003283bool SharedFunctionInfo::optimization_disabled() {
3284 return BooleanBit::get(compiler_hints(), kOptimizationDisabled);
3285}
3286
3287
3288void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3289 set_compiler_hints(BooleanBit::set(compiler_hints(),
3290 kOptimizationDisabled,
3291 disable));
3292 // If disabling optimizations we reflect that in the code object so
3293 // it will not be counted as optimizable code.
3294 if ((code()->kind() == Code::FUNCTION) && disable) {
3295 code()->set_optimizable(false);
3296 }
3297}
3298
3299
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003300bool SharedFunctionInfo::strict_mode() {
3301 return BooleanBit::get(compiler_hints(), kStrictModeFunction);
3302}
3303
3304
3305void SharedFunctionInfo::set_strict_mode(bool value) {
3306 set_compiler_hints(BooleanBit::set(compiler_hints(),
3307 kStrictModeFunction,
3308 value));
3309}
3310
3311
ricow@chromium.org6fe7a8e2011-05-13 07:57:29 +00003312bool SharedFunctionInfo::es5_native() {
3313 return BooleanBit::get(compiler_hints(), kES5Native);
3314}
3315
3316
3317void SharedFunctionInfo::set_es5_native(bool value) {
3318 set_compiler_hints(BooleanBit::set(compiler_hints(),
3319 kES5Native,
3320 value));
3321}
3322
3323
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003324ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3325ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3326
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003327bool Script::HasValidSource() {
3328 Object* src = this->source();
3329 if (!src->IsString()) return true;
3330 String* src_str = String::cast(src);
3331 if (!StringShape(src_str).IsExternal()) return true;
3332 if (src_str->IsAsciiRepresentation()) {
3333 return ExternalAsciiString::cast(src)->resource() != NULL;
3334 } else if (src_str->IsTwoByteRepresentation()) {
3335 return ExternalTwoByteString::cast(src)->resource() != NULL;
3336 }
3337 return true;
3338}
3339
3340
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003341void SharedFunctionInfo::DontAdaptArguments() {
3342 ASSERT(code()->kind() == Code::BUILTIN);
3343 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3344}
3345
3346
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003347int SharedFunctionInfo::start_position() {
3348 return start_position_and_type() >> kStartPositionShift;
3349}
3350
3351
3352void SharedFunctionInfo::set_start_position(int start_position) {
3353 set_start_position_and_type((start_position << kStartPositionShift)
3354 | (start_position_and_type() & ~kStartPositionMask));
3355}
3356
3357
3358Code* SharedFunctionInfo::code() {
3359 return Code::cast(READ_FIELD(this, kCodeOffset));
3360}
3361
3362
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003363Code* SharedFunctionInfo::unchecked_code() {
3364 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3365}
3366
3367
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003368void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003369 WRITE_FIELD(this, kCodeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003370 ASSERT(!Isolate::Current()->heap()->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003371}
3372
3373
ager@chromium.orgb5737492010-07-15 09:29:43 +00003374SerializedScopeInfo* SharedFunctionInfo::scope_info() {
3375 return reinterpret_cast<SerializedScopeInfo*>(
3376 READ_FIELD(this, kScopeInfoOffset));
3377}
3378
3379
3380void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
3381 WriteBarrierMode mode) {
3382 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003383 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kScopeInfoOffset, mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003384}
3385
3386
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003387Smi* SharedFunctionInfo::deopt_counter() {
3388 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3389}
3390
3391
3392void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3393 WRITE_FIELD(this, kDeoptCounterOffset, value);
3394}
3395
3396
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003397bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003398 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003399 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003400}
3401
3402
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003403bool SharedFunctionInfo::IsApiFunction() {
3404 return function_data()->IsFunctionTemplateInfo();
3405}
3406
3407
3408FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3409 ASSERT(IsApiFunction());
3410 return FunctionTemplateInfo::cast(function_data());
3411}
3412
3413
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003414bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003415 return function_data()->IsSmi();
3416}
3417
3418
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003419BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3420 ASSERT(HasBuiltinFunctionId());
3421 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003422}
3423
3424
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003425int SharedFunctionInfo::code_age() {
3426 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3427}
3428
3429
3430void SharedFunctionInfo::set_code_age(int code_age) {
3431 set_compiler_hints(compiler_hints() |
3432 ((code_age & kCodeAgeMask) << kCodeAgeShift));
3433}
3434
3435
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003436bool SharedFunctionInfo::has_deoptimization_support() {
3437 Code* code = this->code();
3438 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3439}
3440
3441
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003442bool JSFunction::IsBuiltin() {
3443 return context()->global()->IsJSBuiltinsObject();
3444}
3445
3446
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003447bool JSFunction::NeedsArgumentsAdaption() {
3448 return shared()->formal_parameter_count() !=
3449 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3450}
3451
3452
3453bool JSFunction::IsOptimized() {
3454 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3455}
3456
3457
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003458bool JSFunction::IsOptimizable() {
3459 return code()->kind() == Code::FUNCTION && code()->optimizable();
3460}
3461
3462
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003463bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003464 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003465}
3466
3467
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003468Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003469 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003470}
3471
3472
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003473Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003474 return reinterpret_cast<Code*>(
3475 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003476}
3477
3478
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003479void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00003480 // Skip the write barrier because code is never in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003481 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003482 Address entry = value->entry();
3483 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003484}
3485
3486
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003487void JSFunction::ReplaceCode(Code* code) {
3488 bool was_optimized = IsOptimized();
3489 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3490
3491 set_code(code);
3492
3493 // Add/remove the function from the list of optimized functions for this
3494 // context based on the state change.
3495 if (!was_optimized && is_optimized) {
3496 context()->global_context()->AddOptimizedFunction(this);
3497 }
3498 if (was_optimized && !is_optimized) {
3499 context()->global_context()->RemoveOptimizedFunction(this);
3500 }
3501}
3502
3503
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003504Context* JSFunction::context() {
3505 return Context::cast(READ_FIELD(this, kContextOffset));
3506}
3507
3508
3509Object* JSFunction::unchecked_context() {
3510 return READ_FIELD(this, kContextOffset);
3511}
3512
3513
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003514SharedFunctionInfo* JSFunction::unchecked_shared() {
3515 return reinterpret_cast<SharedFunctionInfo*>(
3516 READ_FIELD(this, kSharedFunctionInfoOffset));
3517}
3518
3519
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003520void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003521 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003522 WRITE_FIELD(this, kContextOffset, value);
3523 WRITE_BARRIER(this, kContextOffset);
3524}
3525
3526ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3527 kPrototypeOrInitialMapOffset)
3528
3529
3530Map* JSFunction::initial_map() {
3531 return Map::cast(prototype_or_initial_map());
3532}
3533
3534
3535void JSFunction::set_initial_map(Map* value) {
3536 set_prototype_or_initial_map(value);
3537}
3538
3539
3540bool JSFunction::has_initial_map() {
3541 return prototype_or_initial_map()->IsMap();
3542}
3543
3544
3545bool JSFunction::has_instance_prototype() {
3546 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3547}
3548
3549
3550bool JSFunction::has_prototype() {
3551 return map()->has_non_instance_prototype() || has_instance_prototype();
3552}
3553
3554
3555Object* JSFunction::instance_prototype() {
3556 ASSERT(has_instance_prototype());
3557 if (has_initial_map()) return initial_map()->prototype();
3558 // When there is no initial map and the prototype is a JSObject, the
3559 // initial map field is used for the prototype field.
3560 return prototype_or_initial_map();
3561}
3562
3563
3564Object* JSFunction::prototype() {
3565 ASSERT(has_prototype());
3566 // If the function's prototype property has been set to a non-JSObject
3567 // value, that value is stored in the constructor field of the map.
3568 if (map()->has_non_instance_prototype()) return map()->constructor();
3569 return instance_prototype();
3570}
3571
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003572bool JSFunction::should_have_prototype() {
3573 return map()->function_with_prototype();
3574}
3575
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003576
3577bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003578 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003579}
3580
3581
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003582int JSFunction::NumberOfLiterals() {
3583 return literals()->length();
3584}
3585
3586
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003587Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003588 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003589 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003590}
3591
3592
3593void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3594 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003595 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003596 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
3597 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
3598}
3599
3600
3601Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003602 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003603 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3604}
3605
3606
3607void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3608 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003609 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003610 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003611 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003612}
3613
3614
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003615ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
3616
3617
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003618Address Foreign::address() {
3619 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003620}
3621
3622
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003623void Foreign::set_address(Address value) {
3624 WRITE_INTPTR_FIELD(this, kAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003625}
3626
3627
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003628ACCESSORS(JSValue, value, Object, kValueOffset)
3629
3630
3631JSValue* JSValue::cast(Object* obj) {
3632 ASSERT(obj->IsJSValue());
3633 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3634 return reinterpret_cast<JSValue*>(obj);
3635}
3636
3637
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003638ACCESSORS(JSMessageObject, type, String, kTypeOffset)
3639ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
3640ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
3641ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
3642ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
3643SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
3644SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
3645
3646
3647JSMessageObject* JSMessageObject::cast(Object* obj) {
3648 ASSERT(obj->IsJSMessageObject());
3649 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
3650 return reinterpret_cast<JSMessageObject*>(obj);
3651}
3652
3653
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003654INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003655ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003656ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003657ACCESSORS(Code, next_code_flushing_candidate,
3658 Object, kNextCodeFlushingCandidateOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003659
3660
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003661byte* Code::instruction_start() {
3662 return FIELD_ADDR(this, kHeaderSize);
3663}
3664
3665
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003666byte* Code::instruction_end() {
3667 return instruction_start() + instruction_size();
3668}
3669
3670
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003671int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003672 return RoundUp(instruction_size(), kObjectAlignment);
3673}
3674
3675
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003676FixedArray* Code::unchecked_deoptimization_data() {
3677 return reinterpret_cast<FixedArray*>(
3678 READ_FIELD(this, kDeoptimizationDataOffset));
3679}
3680
3681
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003682ByteArray* Code::unchecked_relocation_info() {
3683 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003684}
3685
3686
3687byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003688 return unchecked_relocation_info()->GetDataStartAddress();
3689}
3690
3691
3692int Code::relocation_size() {
3693 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003694}
3695
3696
3697byte* Code::entry() {
3698 return instruction_start();
3699}
3700
3701
3702bool Code::contains(byte* pc) {
3703 return (instruction_start() <= pc) &&
ricow@chromium.org65fae842010-08-25 15:26:24 +00003704 (pc <= instruction_start() + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003705}
3706
3707
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003708ACCESSORS(JSArray, length, Object, kLengthOffset)
3709
3710
ager@chromium.org236ad962008-09-25 09:45:57 +00003711ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00003712
3713
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003714JSRegExp::Type JSRegExp::TypeTag() {
3715 Object* data = this->data();
3716 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
3717 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
3718 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00003719}
3720
3721
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00003722int JSRegExp::CaptureCount() {
3723 switch (TypeTag()) {
3724 case ATOM:
3725 return 0;
3726 case IRREGEXP:
3727 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
3728 default:
3729 UNREACHABLE();
3730 return -1;
3731 }
3732}
3733
3734
ager@chromium.orga74f0da2008-12-03 16:05:52 +00003735JSRegExp::Flags JSRegExp::GetFlags() {
3736 ASSERT(this->data()->IsFixedArray());
3737 Object* data = this->data();
3738 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
3739 return Flags(smi->value());
3740}
3741
3742
3743String* JSRegExp::Pattern() {
3744 ASSERT(this->data()->IsFixedArray());
3745 Object* data = this->data();
3746 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
3747 return pattern;
3748}
3749
3750
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003751Object* JSRegExp::DataAt(int index) {
3752 ASSERT(TypeTag() != NOT_COMPILED);
3753 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00003754}
3755
3756
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003757void JSRegExp::SetDataAt(int index, Object* value) {
3758 ASSERT(TypeTag() != NOT_COMPILED);
3759 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
3760 FixedArray::cast(data())->set(index, value);
3761}
3762
3763
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003764JSObject::ElementsKind JSObject::GetElementsKind() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003765 if (map()->has_fast_elements()) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003766 ASSERT(elements()->map() == GetHeap()->fixed_array_map() ||
3767 elements()->map() == GetHeap()->fixed_cow_array_map());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003768 return FAST_ELEMENTS;
3769 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003770 HeapObject* array = elements();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003771 if (array->IsFixedArray()) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003772 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a
3773 // FixedArray, but FAST_ELEMENTS is already handled above.
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003774 ASSERT(array->IsDictionary());
3775 return DICTIONARY_ELEMENTS;
3776 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003777 ASSERT(!map()->has_fast_elements());
ager@chromium.org3811b432009-10-28 14:53:37 +00003778 if (array->IsExternalArray()) {
3779 switch (array->map()->instance_type()) {
3780 case EXTERNAL_BYTE_ARRAY_TYPE:
3781 return EXTERNAL_BYTE_ELEMENTS;
3782 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
3783 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3784 case EXTERNAL_SHORT_ARRAY_TYPE:
3785 return EXTERNAL_SHORT_ELEMENTS;
3786 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
3787 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3788 case EXTERNAL_INT_ARRAY_TYPE:
3789 return EXTERNAL_INT_ELEMENTS;
3790 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
3791 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003792 case EXTERNAL_FLOAT_ARRAY_TYPE:
3793 return EXTERNAL_FLOAT_ELEMENTS;
3794 case EXTERNAL_DOUBLE_ARRAY_TYPE:
3795 return EXTERNAL_DOUBLE_ELEMENTS;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003796 case EXTERNAL_PIXEL_ARRAY_TYPE:
3797 return EXTERNAL_PIXEL_ELEMENTS;
ager@chromium.org3811b432009-10-28 14:53:37 +00003798 default:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003799 break;
ager@chromium.org3811b432009-10-28 14:53:37 +00003800 }
3801 }
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003802 UNREACHABLE();
3803 return DICTIONARY_ELEMENTS;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003804}
3805
3806
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003807bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003808 return GetElementsKind() == FAST_ELEMENTS;
3809}
3810
3811
3812bool JSObject::HasDictionaryElements() {
3813 return GetElementsKind() == DICTIONARY_ELEMENTS;
3814}
3815
3816
ager@chromium.org3811b432009-10-28 14:53:37 +00003817bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003818 HeapObject* array = elements();
3819 ASSERT(array != NULL);
3820 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00003821}
3822
3823
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003824#define EXTERNAL_ELEMENTS_CHECK(name, type) \
3825bool JSObject::HasExternal##name##Elements() { \
3826 HeapObject* array = elements(); \
3827 ASSERT(array != NULL); \
3828 if (!array->IsHeapObject()) \
3829 return false; \
3830 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00003831}
3832
3833
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003834EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
3835EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
3836EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
3837EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
3838 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
3839EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
3840EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
3841 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
3842EXTERNAL_ELEMENTS_CHECK(Float,
3843 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003844EXTERNAL_ELEMENTS_CHECK(Double,
3845 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003846EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00003847
3848
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003849bool JSObject::HasNamedInterceptor() {
3850 return map()->has_named_interceptor();
3851}
3852
3853
3854bool JSObject::HasIndexedInterceptor() {
3855 return map()->has_indexed_interceptor();
3856}
3857
3858
ager@chromium.org5c838252010-02-19 08:53:10 +00003859bool JSObject::AllowsSetElementsLength() {
3860 bool result = elements()->IsFixedArray();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003861 ASSERT(result == !HasExternalArrayElements());
ager@chromium.org5c838252010-02-19 08:53:10 +00003862 return result;
3863}
3864
3865
lrn@chromium.org303ada72010-10-27 09:33:13 +00003866MaybeObject* JSObject::EnsureWritableFastElements() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003867 ASSERT(HasFastElements());
3868 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003869 Isolate* isolate = GetIsolate();
3870 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003871 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003872 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
3873 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00003874 if (!maybe_writable_elems->ToObject(&writable_elems)) {
3875 return maybe_writable_elems;
3876 }
3877 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003878 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003879 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003880 return writable_elems;
3881}
3882
3883
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003884StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003885 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003886 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003887}
3888
3889
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003890NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003891 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003892 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003893}
3894
3895
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003896bool String::IsHashFieldComputed(uint32_t field) {
3897 return (field & kHashNotComputedMask) == 0;
3898}
3899
3900
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003901bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003902 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003903}
3904
3905
3906uint32_t String::Hash() {
3907 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003908 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003909 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003910 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003911 return ComputeAndSetHash();
3912}
3913
3914
ager@chromium.org7c537e22008-10-16 08:43:32 +00003915StringHasher::StringHasher(int length)
3916 : length_(length),
3917 raw_running_hash_(0),
3918 array_index_(0),
3919 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
3920 is_first_char_(true),
3921 is_valid_(true) { }
3922
3923
3924bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003925 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00003926}
3927
3928
3929void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003930 // Use the Jenkins one-at-a-time hash function to update the hash
3931 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003932 raw_running_hash_ += c;
3933 raw_running_hash_ += (raw_running_hash_ << 10);
3934 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003935 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003936 if (is_array_index_) {
3937 if (c < '0' || c > '9') {
3938 is_array_index_ = false;
3939 } else {
3940 int d = c - '0';
3941 if (is_first_char_) {
3942 is_first_char_ = false;
3943 if (c == '0' && length_ > 1) {
3944 is_array_index_ = false;
3945 return;
3946 }
3947 }
3948 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
3949 is_array_index_ = false;
3950 } else {
3951 array_index_ = array_index_ * 10 + d;
3952 }
3953 }
3954 }
3955}
3956
3957
3958void StringHasher::AddCharacterNoIndex(uc32 c) {
3959 ASSERT(!is_array_index());
3960 raw_running_hash_ += c;
3961 raw_running_hash_ += (raw_running_hash_ << 10);
3962 raw_running_hash_ ^= (raw_running_hash_ >> 6);
3963}
3964
3965
3966uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003967 // Get the calculated raw hash value and do some more bit ops to distribute
3968 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003969 uint32_t result = raw_running_hash_;
3970 result += (result << 3);
3971 result ^= (result >> 11);
3972 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003973 if (result == 0) {
3974 result = 27;
3975 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00003976 return result;
3977}
3978
3979
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003980template <typename schar>
3981uint32_t HashSequentialString(const schar* chars, int length) {
3982 StringHasher hasher(length);
3983 if (!hasher.has_trivial_hash()) {
3984 int i;
3985 for (i = 0; hasher.is_array_index() && (i < length); i++) {
3986 hasher.AddCharacter(chars[i]);
3987 }
3988 for (; i < length; i++) {
3989 hasher.AddCharacterNoIndex(chars[i]);
3990 }
3991 }
3992 return hasher.GetHashField();
3993}
3994
3995
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003996bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003997 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003998 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
3999 return false;
4000 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004001 return SlowAsArrayIndex(index);
4002}
4003
4004
4005Object* JSObject::GetPrototype() {
4006 return JSObject::cast(this)->map()->prototype();
4007}
4008
4009
4010PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
4011 return GetPropertyAttributeWithReceiver(this, key);
4012}
4013
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004014// TODO(504): this may be useful in other places too where JSGlobalProxy
4015// is used.
4016Object* JSObject::BypassGlobalProxy() {
4017 if (IsJSGlobalProxy()) {
4018 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004019 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004020 ASSERT(proto->IsJSGlobalObject());
4021 return proto;
4022 }
4023 return this;
4024}
4025
4026
4027bool JSObject::HasHiddenPropertiesObject() {
4028 ASSERT(!IsJSGlobalProxy());
4029 return GetPropertyAttributePostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004030 GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004031 false) != ABSENT;
4032}
4033
4034
4035Object* JSObject::GetHiddenPropertiesObject() {
4036 ASSERT(!IsJSGlobalProxy());
4037 PropertyAttributes attributes;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004038 // You can't install a getter on a property indexed by the hidden symbol,
4039 // so we can be sure that GetLocalPropertyPostInterceptor returns a real
4040 // object.
4041 Object* result =
4042 GetLocalPropertyPostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004043 GetHeap()->hidden_symbol(),
lrn@chromium.org303ada72010-10-27 09:33:13 +00004044 &attributes)->ToObjectUnchecked();
4045 return result;
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004046}
4047
4048
lrn@chromium.org303ada72010-10-27 09:33:13 +00004049MaybeObject* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004050 ASSERT(!IsJSGlobalProxy());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004051 return SetPropertyPostInterceptor(GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004052 hidden_obj,
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00004053 DONT_ENUM,
4054 kNonStrictMode);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004055}
4056
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004057
4058bool JSObject::HasElement(uint32_t index) {
4059 return HasElementWithReceiver(this, index);
4060}
4061
4062
4063bool AccessorInfo::all_can_read() {
4064 return BooleanBit::get(flag(), kAllCanReadBit);
4065}
4066
4067
4068void AccessorInfo::set_all_can_read(bool value) {
4069 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4070}
4071
4072
4073bool AccessorInfo::all_can_write() {
4074 return BooleanBit::get(flag(), kAllCanWriteBit);
4075}
4076
4077
4078void AccessorInfo::set_all_can_write(bool value) {
4079 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4080}
4081
4082
ager@chromium.org870a0b62008-11-04 11:43:05 +00004083bool AccessorInfo::prohibits_overwriting() {
4084 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4085}
4086
4087
4088void AccessorInfo::set_prohibits_overwriting(bool value) {
4089 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4090}
4091
4092
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004093PropertyAttributes AccessorInfo::property_attributes() {
4094 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4095}
4096
4097
4098void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
4099 ASSERT(AttributesField::is_valid(attributes));
4100 int rest_value = flag()->value() & ~AttributesField::mask();
4101 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
4102}
4103
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004104
4105template<typename Shape, typename Key>
4106void Dictionary<Shape, Key>::SetEntry(int entry,
4107 Object* key,
4108 Object* value) {
4109 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4110}
4111
4112
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004113template<typename Shape, typename Key>
4114void Dictionary<Shape, Key>::SetEntry(int entry,
4115 Object* key,
4116 Object* value,
4117 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004118 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004119 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004120 AssertNoAllocation no_gc;
4121 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004122 FixedArray::set(index, key, mode);
4123 FixedArray::set(index+1, value, mode);
4124 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004125}
4126
4127
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004128bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4129 ASSERT(other->IsNumber());
4130 return key == static_cast<uint32_t>(other->Number());
4131}
4132
4133
4134uint32_t NumberDictionaryShape::Hash(uint32_t key) {
4135 return ComputeIntegerHash(key);
4136}
4137
4138
4139uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
4140 ASSERT(other->IsNumber());
4141 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
4142}
4143
4144
4145MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4146 return Isolate::Current()->heap()->NumberFromUint32(key);
4147}
4148
4149
4150bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4151 // We know that all entries in a hash table had their hash keys created.
4152 // Use that knowledge to have fast failure.
4153 if (key->Hash() != String::cast(other)->Hash()) return false;
4154 return key->Equals(String::cast(other));
4155}
4156
4157
4158uint32_t StringDictionaryShape::Hash(String* key) {
4159 return key->Hash();
4160}
4161
4162
4163uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4164 return String::cast(other)->Hash();
4165}
4166
4167
4168MaybeObject* StringDictionaryShape::AsObject(String* key) {
4169 return key;
4170}
4171
4172
4173void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004174 // No write barrier is needed since empty_fixed_array is not in new space.
4175 // Please note this function is used during marking:
4176 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004177 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4178 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004179}
4180
4181
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004182void JSArray::EnsureSize(int required_size) {
4183 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004184 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004185 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4186 if (elts->length() < required_size) {
4187 // Doubling in size would be overkill, but leave some slack to avoid
4188 // constantly growing.
4189 Expand(required_size + (required_size >> 3));
4190 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004191 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004192 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4193 // Expand will allocate a new backing store in new space even if the size
4194 // we asked for isn't larger than what we had before.
4195 Expand(required_size);
4196 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004197}
4198
4199
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004200void JSArray::set_length(Smi* length) {
4201 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4202}
4203
4204
ager@chromium.org7c537e22008-10-16 08:43:32 +00004205void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004206 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004207 set_elements(storage);
4208}
4209
4210
lrn@chromium.org303ada72010-10-27 09:33:13 +00004211MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004212 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004213 return GetHeap()->CopyFixedArray(this);
4214}
4215
4216
4217Relocatable::Relocatable(Isolate* isolate) {
4218 ASSERT(isolate == Isolate::Current());
4219 isolate_ = isolate;
4220 prev_ = isolate->relocatable_top();
4221 isolate->set_relocatable_top(this);
4222}
4223
4224
4225Relocatable::~Relocatable() {
4226 ASSERT(isolate_ == Isolate::Current());
4227 ASSERT_EQ(isolate_->relocatable_top(), this);
4228 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004229}
4230
4231
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004232int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4233 return map->instance_size();
4234}
4235
4236
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004237void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004238 v->VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004239 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004240}
4241
4242
4243template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004244void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004245 StaticVisitor::VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004246 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004247}
4248
4249
4250void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4251 typedef v8::String::ExternalAsciiStringResource Resource;
4252 v->VisitExternalAsciiString(
4253 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4254}
4255
4256
4257template<typename StaticVisitor>
4258void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4259 typedef v8::String::ExternalAsciiStringResource Resource;
4260 StaticVisitor::VisitExternalAsciiString(
4261 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4262}
4263
4264
4265void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4266 typedef v8::String::ExternalStringResource Resource;
4267 v->VisitExternalTwoByteString(
4268 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4269}
4270
4271
4272template<typename StaticVisitor>
4273void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4274 typedef v8::String::ExternalStringResource Resource;
4275 StaticVisitor::VisitExternalTwoByteString(
4276 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4277}
4278
4279#define SLOT_ADDR(obj, offset) \
4280 reinterpret_cast<Object**>((obj)->address() + offset)
4281
4282template<int start_offset, int end_offset, int size>
4283void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4284 HeapObject* obj,
4285 ObjectVisitor* v) {
4286 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4287}
4288
4289
4290template<int start_offset>
4291void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4292 int object_size,
4293 ObjectVisitor* v) {
4294 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4295}
4296
4297#undef SLOT_ADDR
4298
4299
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004300#undef CAST_ACCESSOR
4301#undef INT_ACCESSORS
4302#undef SMI_ACCESSORS
4303#undef ACCESSORS
4304#undef FIELD_ADDR
4305#undef READ_FIELD
4306#undef WRITE_FIELD
4307#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004308#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004309#undef READ_MEMADDR_FIELD
4310#undef WRITE_MEMADDR_FIELD
4311#undef READ_DOUBLE_FIELD
4312#undef WRITE_DOUBLE_FIELD
4313#undef READ_INT_FIELD
4314#undef WRITE_INT_FIELD
4315#undef READ_SHORT_FIELD
4316#undef WRITE_SHORT_FIELD
4317#undef READ_BYTE_FIELD
4318#undef WRITE_BYTE_FIELD
4319
4320
4321} } // namespace v8::internal
4322
4323#endif // V8_OBJECTS_INL_H_