blob: 29a368caaf2c32674ee6266aa65bc59edde63f37 [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
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000449bool Object::IsJSReceiver() {
450 return IsHeapObject() &&
451 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE;
452}
453
454
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000455bool Object::IsJSObject() {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000456 return IsJSReceiver() && !IsJSProxy();
457}
458
459
460bool Object::IsJSProxy() {
461 return Object::IsHeapObject() &&
462 (HeapObject::cast(this)->map()->instance_type() == JS_PROXY_TYPE ||
463 HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_PROXY_TYPE);
464}
465
466
467bool Object::IsJSFunctionProxy() {
468 return Object::IsHeapObject() &&
469 HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_PROXY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000470}
471
472
ager@chromium.org32912102009-01-16 10:38:43 +0000473bool Object::IsJSContextExtensionObject() {
474 return IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000475 && (HeapObject::cast(this)->map()->instance_type() ==
476 JS_CONTEXT_EXTENSION_OBJECT_TYPE);
ager@chromium.org32912102009-01-16 10:38:43 +0000477}
478
479
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000480bool Object::IsMap() {
481 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000482 && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000483}
484
485
486bool Object::IsFixedArray() {
487 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000488 && HeapObject::cast(this)->map()->instance_type() == FIXED_ARRAY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000489}
490
491
492bool Object::IsDescriptorArray() {
493 return IsFixedArray();
494}
495
496
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000497bool Object::IsDeoptimizationInputData() {
498 // Must be a fixed array.
499 if (!IsFixedArray()) return false;
500
501 // There's no sure way to detect the difference between a fixed array and
502 // a deoptimization data array. Since this is used for asserts we can
503 // check that the length is zero or else the fixed size plus a multiple of
504 // the entry size.
505 int length = FixedArray::cast(this)->length();
506 if (length == 0) return true;
507
508 length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
509 return length >= 0 &&
510 length % DeoptimizationInputData::kDeoptEntrySize == 0;
511}
512
513
514bool Object::IsDeoptimizationOutputData() {
515 if (!IsFixedArray()) return false;
516 // There's actually no way to see the difference between a fixed array and
517 // a deoptimization data array. Since this is used for asserts we can check
518 // that the length is plausible though.
519 if (FixedArray::cast(this)->length() % 2 != 0) return false;
520 return true;
521}
522
523
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000524bool Object::IsContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000525 if (Object::IsHeapObject()) {
526 Heap* heap = HeapObject::cast(this)->GetHeap();
527 return (HeapObject::cast(this)->map() == heap->context_map() ||
528 HeapObject::cast(this)->map() == heap->catch_context_map() ||
529 HeapObject::cast(this)->map() == heap->global_context_map());
530 }
531 return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000532}
533
534
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000535bool Object::IsCatchContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000536 return Object::IsHeapObject() &&
537 HeapObject::cast(this)->map() ==
538 HeapObject::cast(this)->GetHeap()->catch_context_map();
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000539}
540
541
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000542bool Object::IsGlobalContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000543 return Object::IsHeapObject() &&
544 HeapObject::cast(this)->map() ==
545 HeapObject::cast(this)->GetHeap()->global_context_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000546}
547
548
549bool Object::IsJSFunction() {
550 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000551 && HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000552}
553
554
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000555template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000556 return obj->IsJSFunction();
557}
558
559
560bool Object::IsCode() {
561 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000562 && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000563}
564
565
566bool Object::IsOddball() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000567 ASSERT(HEAP->is_safe_to_read_maps());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000568 return Object::IsHeapObject()
569 && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE;
570}
571
572
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000573bool Object::IsJSGlobalPropertyCell() {
574 return Object::IsHeapObject()
575 && HeapObject::cast(this)->map()->instance_type()
576 == JS_GLOBAL_PROPERTY_CELL_TYPE;
577}
578
579
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000580bool Object::IsSharedFunctionInfo() {
581 return Object::IsHeapObject() &&
582 (HeapObject::cast(this)->map()->instance_type() ==
583 SHARED_FUNCTION_INFO_TYPE);
584}
585
586
587bool Object::IsJSValue() {
588 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000589 && HeapObject::cast(this)->map()->instance_type() == JS_VALUE_TYPE;
590}
591
592
593bool Object::IsJSMessageObject() {
594 return Object::IsHeapObject()
595 && (HeapObject::cast(this)->map()->instance_type() ==
596 JS_MESSAGE_OBJECT_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000597}
598
599
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000600bool Object::IsStringWrapper() {
601 return IsJSValue() && JSValue::cast(this)->value()->IsString();
602}
603
604
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000605bool Object::IsForeign() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000606 return Object::IsHeapObject()
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000607 && HeapObject::cast(this)->map()->instance_type() == FOREIGN_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000608}
609
610
611bool Object::IsBoolean() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000612 return IsOddball() &&
613 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000614}
615
616
617bool Object::IsJSArray() {
618 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000619 && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000620}
621
622
ager@chromium.org236ad962008-09-25 09:45:57 +0000623bool Object::IsJSRegExp() {
624 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000625 && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
ager@chromium.org236ad962008-09-25 09:45:57 +0000626}
627
628
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000629template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000630 return obj->IsJSArray();
631}
632
633
634bool Object::IsHashTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000635 return Object::IsHeapObject() &&
636 HeapObject::cast(this)->map() ==
637 HeapObject::cast(this)->GetHeap()->hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000638}
639
640
641bool Object::IsDictionary() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000642 return IsHashTable() && this !=
643 HeapObject::cast(this)->GetHeap()->symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000644}
645
646
647bool Object::IsSymbolTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000648 return IsHashTable() && this ==
649 HeapObject::cast(this)->GetHeap()->raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000650}
651
652
ager@chromium.orgac091b72010-05-05 07:34:42 +0000653bool Object::IsJSFunctionResultCache() {
654 if (!IsFixedArray()) return false;
655 FixedArray* self = FixedArray::cast(this);
656 int length = self->length();
657 if (length < JSFunctionResultCache::kEntriesIndex) return false;
658 if ((length - JSFunctionResultCache::kEntriesIndex)
659 % JSFunctionResultCache::kEntrySize != 0) {
660 return false;
661 }
662#ifdef DEBUG
663 reinterpret_cast<JSFunctionResultCache*>(this)->JSFunctionResultCacheVerify();
664#endif
665 return true;
666}
667
668
ricow@chromium.org65fae842010-08-25 15:26:24 +0000669bool Object::IsNormalizedMapCache() {
670 if (!IsFixedArray()) return false;
671 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
672 return false;
673 }
674#ifdef DEBUG
675 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
676#endif
677 return true;
678}
679
680
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000681bool Object::IsCompilationCacheTable() {
682 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000683}
684
685
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000686bool Object::IsCodeCacheHashTable() {
687 return IsHashTable();
688}
689
690
ager@chromium.org236ad962008-09-25 09:45:57 +0000691bool Object::IsMapCache() {
692 return IsHashTable();
693}
694
695
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000696bool Object::IsPrimitive() {
697 return IsOddball() || IsNumber() || IsString();
698}
699
700
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000701bool Object::IsJSGlobalProxy() {
702 bool result = IsHeapObject() &&
703 (HeapObject::cast(this)->map()->instance_type() ==
704 JS_GLOBAL_PROXY_TYPE);
705 ASSERT(!result || IsAccessCheckNeeded());
706 return result;
707}
708
709
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000710bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000711 if (!IsHeapObject()) return false;
712
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000713 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000714 return type == JS_GLOBAL_OBJECT_TYPE ||
715 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000716}
717
718
719bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000720 return IsHeapObject() &&
721 (HeapObject::cast(this)->map()->instance_type() ==
722 JS_GLOBAL_OBJECT_TYPE);
723}
724
725
726bool Object::IsJSBuiltinsObject() {
727 return IsHeapObject() &&
728 (HeapObject::cast(this)->map()->instance_type() ==
729 JS_BUILTINS_OBJECT_TYPE);
730}
731
732
733bool Object::IsUndetectableObject() {
734 return IsHeapObject()
735 && HeapObject::cast(this)->map()->is_undetectable();
736}
737
738
739bool Object::IsAccessCheckNeeded() {
740 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000741 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000742}
743
744
745bool Object::IsStruct() {
746 if (!IsHeapObject()) return false;
747 switch (HeapObject::cast(this)->map()->instance_type()) {
748#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
749 STRUCT_LIST(MAKE_STRUCT_CASE)
750#undef MAKE_STRUCT_CASE
751 default: return false;
752 }
753}
754
755
756#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
757 bool Object::Is##Name() { \
758 return Object::IsHeapObject() \
759 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
760 }
761 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
762#undef MAKE_STRUCT_PREDICATE
763
764
765bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000766 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000767}
768
769
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000770bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000771 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
772}
773
774
775bool Object::IsTheHole() {
776 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000777}
778
779
780bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000781 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000782}
783
784
785bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000786 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000787}
788
789
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000790bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000791 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000792}
793
794
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000795double Object::Number() {
796 ASSERT(IsNumber());
797 return IsSmi()
798 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
799 : reinterpret_cast<HeapNumber*>(this)->value();
800}
801
802
lrn@chromium.org303ada72010-10-27 09:33:13 +0000803MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000804 if (IsSmi()) return this;
805 if (IsHeapNumber()) {
806 double value = HeapNumber::cast(this)->value();
807 int int_value = FastD2I(value);
808 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
809 return Smi::FromInt(int_value);
810 }
811 }
812 return Failure::Exception();
813}
814
815
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000816bool Object::HasSpecificClassOf(String* name) {
817 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
818}
819
820
lrn@chromium.org303ada72010-10-27 09:33:13 +0000821MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000822 // GetElement can trigger a getter which can cause allocation.
823 // This was not always the case. This ASSERT is here to catch
824 // leftover incorrect uses.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000825 ASSERT(HEAP->IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000826 return GetElementWithReceiver(this, index);
827}
828
829
lrn@chromium.org303ada72010-10-27 09:33:13 +0000830Object* Object::GetElementNoExceptionThrown(uint32_t index) {
831 MaybeObject* maybe = GetElementWithReceiver(this, index);
832 ASSERT(!maybe->IsFailure());
833 Object* result = NULL; // Initialization to please compiler.
834 maybe->ToObject(&result);
835 return result;
836}
837
838
839MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000840 PropertyAttributes attributes;
841 return GetPropertyWithReceiver(this, key, &attributes);
842}
843
844
lrn@chromium.org303ada72010-10-27 09:33:13 +0000845MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000846 return GetPropertyWithReceiver(this, key, attributes);
847}
848
849
850#define FIELD_ADDR(p, offset) \
851 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
852
853#define READ_FIELD(p, offset) \
854 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
855
856#define WRITE_FIELD(p, offset, value) \
857 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
858
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000859// TODO(isolates): Pass heap in to these macros.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000860#define WRITE_BARRIER(object, offset) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000861 object->GetHeap()->RecordWrite(object->address(), offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000862
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000863// CONDITIONAL_WRITE_BARRIER must be issued after the actual
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000864// write due to the assert validating the written value.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000865#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, mode) \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000866 if (mode == UPDATE_WRITE_BARRIER) { \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000867 heap->RecordWrite(object->address(), offset); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000868 } else { \
869 ASSERT(mode == SKIP_WRITE_BARRIER); \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000870 ASSERT(heap->InNewSpace(object) || \
871 !heap->InNewSpace(READ_FIELD(object, offset)) || \
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000872 Page::FromAddress(object->address())-> \
873 IsRegionDirty(object->address() + offset)); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000874 }
875
lrn@chromium.org7516f052011-03-30 08:52:27 +0000876#ifndef V8_TARGET_ARCH_MIPS
877 #define READ_DOUBLE_FIELD(p, offset) \
878 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
879#else // V8_TARGET_ARCH_MIPS
880 // Prevent gcc from using load-double (mips ldc1) on (possibly)
881 // non-64-bit aligned HeapNumber::value.
882 static inline double read_double_field(HeapNumber* p, int offset) {
883 union conversion {
884 double d;
885 uint32_t u[2];
886 } c;
887 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
888 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
889 return c.d;
890 }
891 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
892#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000893
lrn@chromium.org7516f052011-03-30 08:52:27 +0000894
895#ifndef V8_TARGET_ARCH_MIPS
896 #define WRITE_DOUBLE_FIELD(p, offset, value) \
897 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
898#else // V8_TARGET_ARCH_MIPS
899 // Prevent gcc from using store-double (mips sdc1) on (possibly)
900 // non-64-bit aligned HeapNumber::value.
901 static inline void write_double_field(HeapNumber* p, int offset,
902 double value) {
903 union conversion {
904 double d;
905 uint32_t u[2];
906 } c;
907 c.d = value;
908 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
909 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
910 }
911 #define WRITE_DOUBLE_FIELD(p, offset, value) \
912 write_double_field(p, offset, value)
913#endif // V8_TARGET_ARCH_MIPS
914
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000915
916#define READ_INT_FIELD(p, offset) \
917 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
918
919#define WRITE_INT_FIELD(p, offset, value) \
920 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
921
ager@chromium.org3e875802009-06-29 08:26:34 +0000922#define READ_INTPTR_FIELD(p, offset) \
923 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
924
925#define WRITE_INTPTR_FIELD(p, offset, value) \
926 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
927
ager@chromium.org7c537e22008-10-16 08:43:32 +0000928#define READ_UINT32_FIELD(p, offset) \
929 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
930
931#define WRITE_UINT32_FIELD(p, offset, value) \
932 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
933
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000934#define READ_SHORT_FIELD(p, offset) \
935 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
936
937#define WRITE_SHORT_FIELD(p, offset, value) \
938 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
939
940#define READ_BYTE_FIELD(p, offset) \
941 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
942
943#define WRITE_BYTE_FIELD(p, offset, value) \
944 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
945
946
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000947Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
948 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000949}
950
951
952int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000953 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000954}
955
956
957Smi* Smi::FromInt(int value) {
958 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000959 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000960 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000961 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000962 return reinterpret_cast<Smi*>(tagged_value);
963}
964
965
966Smi* Smi::FromIntptr(intptr_t value) {
967 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000968 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
969 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000970}
971
972
973Failure::Type Failure::type() const {
974 return static_cast<Type>(value() & kFailureTypeTagMask);
975}
976
977
978bool Failure::IsInternalError() const {
979 return type() == INTERNAL_ERROR;
980}
981
982
983bool Failure::IsOutOfMemoryException() const {
984 return type() == OUT_OF_MEMORY_EXCEPTION;
985}
986
987
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000988AllocationSpace Failure::allocation_space() const {
989 ASSERT_EQ(RETRY_AFTER_GC, type());
990 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
991 & kSpaceTagMask);
992}
993
994
995Failure* Failure::InternalError() {
996 return Construct(INTERNAL_ERROR);
997}
998
999
1000Failure* Failure::Exception() {
1001 return Construct(EXCEPTION);
1002}
1003
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00001004
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001005Failure* Failure::OutOfMemoryException() {
1006 return Construct(OUT_OF_MEMORY_EXCEPTION);
1007}
1008
1009
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001010intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001011 return static_cast<intptr_t>(
1012 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001013}
1014
1015
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001016Failure* Failure::RetryAfterGC() {
1017 return RetryAfterGC(NEW_SPACE);
1018}
1019
1020
1021Failure* Failure::RetryAfterGC(AllocationSpace space) {
1022 ASSERT((space & ~kSpaceTagMask) == 0);
1023 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001024}
1025
1026
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001027Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001028 uintptr_t info =
1029 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001030 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001031 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001032}
1033
1034
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001035bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001036#ifdef DEBUG
1037 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1038#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001039
1040#ifdef V8_TARGET_ARCH_X64
1041 // To be representable as a long smi, the value must be a 32-bit integer.
1042 bool result = (value == static_cast<int32_t>(value));
1043#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001044 // To be representable as an tagged small integer, the two
1045 // most-significant bits of 'value' must be either 00 or 11 due to
1046 // sign-extension. To check this we add 01 to the two
1047 // most-significant bits, and check if the most-significant bit is 0
1048 //
1049 // CAUTION: The original code below:
1050 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1051 // may lead to incorrect results according to the C language spec, and
1052 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1053 // compiler may produce undefined results in case of signed integer
1054 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001055 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001056#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001057 ASSERT(result == in_range);
1058 return result;
1059}
1060
1061
kasper.lund7276f142008-07-30 08:49:36 +00001062MapWord MapWord::FromMap(Map* map) {
1063 return MapWord(reinterpret_cast<uintptr_t>(map));
1064}
1065
1066
1067Map* MapWord::ToMap() {
1068 return reinterpret_cast<Map*>(value_);
1069}
1070
1071
1072bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001073 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001074}
1075
1076
1077MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001078 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1079 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001080}
1081
1082
1083HeapObject* MapWord::ToForwardingAddress() {
1084 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001085 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001086}
1087
1088
1089bool MapWord::IsMarked() {
1090 return (value_ & kMarkingMask) == 0;
1091}
1092
1093
1094void MapWord::SetMark() {
1095 value_ &= ~kMarkingMask;
1096}
1097
1098
1099void MapWord::ClearMark() {
1100 value_ |= kMarkingMask;
1101}
1102
1103
1104bool MapWord::IsOverflowed() {
1105 return (value_ & kOverflowMask) != 0;
1106}
1107
1108
1109void MapWord::SetOverflow() {
1110 value_ |= kOverflowMask;
1111}
1112
1113
1114void MapWord::ClearOverflow() {
1115 value_ &= ~kOverflowMask;
1116}
1117
1118
1119MapWord MapWord::EncodeAddress(Address map_address, int offset) {
1120 // Offset is the distance in live bytes from the first live object in the
1121 // same page. The offset between two objects in the same page should not
1122 // exceed the object area size of a page.
1123 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
1124
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001125 uintptr_t compact_offset = offset >> kObjectAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001126 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
1127
1128 Page* map_page = Page::FromAddress(map_address);
1129 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
1130
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001131 uintptr_t map_page_offset =
1132 map_page->Offset(map_address) >> kMapAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001133
1134 uintptr_t encoding =
1135 (compact_offset << kForwardingOffsetShift) |
1136 (map_page_offset << kMapPageOffsetShift) |
1137 (map_page->mc_page_index << kMapPageIndexShift);
1138 return MapWord(encoding);
1139}
1140
1141
1142Address MapWord::DecodeMapAddress(MapSpace* map_space) {
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001143 int map_page_index =
1144 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
kasper.lund7276f142008-07-30 08:49:36 +00001145 ASSERT_MAP_PAGE_INDEX(map_page_index);
1146
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001147 int map_page_offset = static_cast<int>(
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001148 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift) <<
1149 kMapAlignmentBits);
kasper.lund7276f142008-07-30 08:49:36 +00001150
1151 return (map_space->PageAddress(map_page_index) + map_page_offset);
1152}
1153
1154
1155int MapWord::DecodeOffset() {
1156 // The offset field is represented in the kForwardingOffsetBits
1157 // most-significant bits.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001158 uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
1159 ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize));
1160 return static_cast<int>(offset);
kasper.lund7276f142008-07-30 08:49:36 +00001161}
1162
1163
1164MapWord MapWord::FromEncodedAddress(Address address) {
1165 return MapWord(reinterpret_cast<uintptr_t>(address));
1166}
1167
1168
1169Address MapWord::ToEncodedAddress() {
1170 return reinterpret_cast<Address>(value_);
1171}
1172
1173
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001174#ifdef DEBUG
1175void HeapObject::VerifyObjectField(int offset) {
1176 VerifyPointer(READ_FIELD(this, offset));
1177}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001178
1179void HeapObject::VerifySmiField(int offset) {
1180 ASSERT(READ_FIELD(this, offset)->IsSmi());
1181}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001182#endif
1183
1184
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001185Heap* HeapObject::GetHeap() {
1186 // During GC, the map pointer in HeapObject is used in various ways that
1187 // prevent us from retrieving Heap from the map.
1188 // Assert that we are not in GC, implement GC code in a way that it doesn't
1189 // pull heap from the map.
1190 ASSERT(HEAP->is_safe_to_read_maps());
1191 return map()->heap();
1192}
1193
1194
1195Isolate* HeapObject::GetIsolate() {
1196 return GetHeap()->isolate();
1197}
1198
1199
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001200Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001201 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001202}
1203
1204
1205void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001206 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001207}
1208
1209
kasper.lund7276f142008-07-30 08:49:36 +00001210MapWord HeapObject::map_word() {
1211 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1212}
1213
1214
1215void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001216 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001217 // here.
1218 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1219}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001220
1221
1222HeapObject* HeapObject::FromAddress(Address address) {
1223 ASSERT_TAG_ALIGNED(address);
1224 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1225}
1226
1227
1228Address HeapObject::address() {
1229 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1230}
1231
1232
1233int HeapObject::Size() {
1234 return SizeFromMap(map());
1235}
1236
1237
1238void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1239 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1240 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1241}
1242
1243
1244void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1245 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1246}
1247
1248
kasper.lund7276f142008-07-30 08:49:36 +00001249bool HeapObject::IsMarked() {
1250 return map_word().IsMarked();
1251}
1252
1253
1254void HeapObject::SetMark() {
1255 ASSERT(!IsMarked());
1256 MapWord first_word = map_word();
1257 first_word.SetMark();
1258 set_map_word(first_word);
1259}
1260
1261
1262void HeapObject::ClearMark() {
1263 ASSERT(IsMarked());
1264 MapWord first_word = map_word();
1265 first_word.ClearMark();
1266 set_map_word(first_word);
1267}
1268
1269
1270bool HeapObject::IsOverflowed() {
1271 return map_word().IsOverflowed();
1272}
1273
1274
1275void HeapObject::SetOverflow() {
1276 MapWord first_word = map_word();
1277 first_word.SetOverflow();
1278 set_map_word(first_word);
1279}
1280
1281
1282void HeapObject::ClearOverflow() {
1283 ASSERT(IsOverflowed());
1284 MapWord first_word = map_word();
1285 first_word.ClearOverflow();
1286 set_map_word(first_word);
1287}
1288
1289
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001290double HeapNumber::value() {
1291 return READ_DOUBLE_FIELD(this, kValueOffset);
1292}
1293
1294
1295void HeapNumber::set_value(double value) {
1296 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1297}
1298
1299
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001300int HeapNumber::get_exponent() {
1301 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1302 kExponentShift) - kExponentBias;
1303}
1304
1305
1306int HeapNumber::get_sign() {
1307 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1308}
1309
1310
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001311ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001312
1313
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001314HeapObject* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001315 Object* array = READ_FIELD(this, kElementsOffset);
1316 // In the assert below Dictionary is covered under FixedArray.
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001317 ASSERT(array->IsFixedArray() || array->IsExternalArray());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001318 return reinterpret_cast<HeapObject*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001319}
1320
1321
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001322void JSObject::set_elements(HeapObject* value, WriteBarrierMode mode) {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001323 ASSERT(map()->has_fast_elements() ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001324 (value->map() == GetHeap()->fixed_array_map() ||
1325 value->map() == GetHeap()->fixed_cow_array_map()));
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001326 // In the assert below Dictionary is covered under FixedArray.
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001327 ASSERT(value->IsFixedArray() || value->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001328 WRITE_FIELD(this, kElementsOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001329 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001330}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001331
1332
1333void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001334 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1335 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001336}
1337
1338
1339void JSObject::initialize_elements() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001340 ASSERT(map()->has_fast_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001341 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1342 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001343}
1344
1345
lrn@chromium.org303ada72010-10-27 09:33:13 +00001346MaybeObject* JSObject::ResetElements() {
1347 Object* obj;
1348 { MaybeObject* maybe_obj = map()->GetFastElementsMap();
1349 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1350 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001351 set_map(Map::cast(obj));
1352 initialize_elements();
1353 return this;
1354}
1355
1356
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001357ACCESSORS(Oddball, to_string, String, kToStringOffset)
1358ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1359
1360
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001361byte Oddball::kind() {
1362 return READ_BYTE_FIELD(this, kKindOffset);
1363}
1364
1365
1366void Oddball::set_kind(byte value) {
1367 WRITE_BYTE_FIELD(this, kKindOffset, value);
1368}
1369
1370
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001371Object* JSGlobalPropertyCell::value() {
1372 return READ_FIELD(this, kValueOffset);
1373}
1374
1375
1376void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1377 // The write barrier is not used for global property cells.
1378 ASSERT(!val->IsJSGlobalPropertyCell());
1379 WRITE_FIELD(this, kValueOffset, val);
1380}
1381
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001382
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001383int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001384 InstanceType type = map()->instance_type();
1385 // Check for the most common kind of JavaScript object before
1386 // falling into the generic switch. This speeds up the internal
1387 // field operations considerably on average.
1388 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1389 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001390 case JS_GLOBAL_PROXY_TYPE:
1391 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001392 case JS_GLOBAL_OBJECT_TYPE:
1393 return JSGlobalObject::kSize;
1394 case JS_BUILTINS_OBJECT_TYPE:
1395 return JSBuiltinsObject::kSize;
1396 case JS_FUNCTION_TYPE:
1397 return JSFunction::kSize;
1398 case JS_VALUE_TYPE:
1399 return JSValue::kSize;
1400 case JS_ARRAY_TYPE:
1401 return JSValue::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001402 case JS_REGEXP_TYPE:
1403 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001404 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001405 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001406 case JS_MESSAGE_OBJECT_TYPE:
1407 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001408 default:
1409 UNREACHABLE();
1410 return 0;
1411 }
1412}
1413
1414
1415int JSObject::GetInternalFieldCount() {
1416 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001417 // Make sure to adjust for the number of in-object properties. These
1418 // properties do contribute to the size, but are not internal fields.
1419 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1420 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001421}
1422
1423
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001424int JSObject::GetInternalFieldOffset(int index) {
1425 ASSERT(index < GetInternalFieldCount() && index >= 0);
1426 return GetHeaderSize() + (kPointerSize * index);
1427}
1428
1429
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001430Object* JSObject::GetInternalField(int index) {
1431 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001432 // Internal objects do follow immediately after the header, whereas in-object
1433 // properties are at the end of the object. Therefore there is no need
1434 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001435 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1436}
1437
1438
1439void JSObject::SetInternalField(int index, Object* value) {
1440 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001441 // Internal objects do follow immediately after the header, whereas in-object
1442 // properties are at the end of the object. Therefore there is no need
1443 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001444 int offset = GetHeaderSize() + (kPointerSize * index);
1445 WRITE_FIELD(this, offset, value);
1446 WRITE_BARRIER(this, offset);
1447}
1448
1449
ager@chromium.org7c537e22008-10-16 08:43:32 +00001450// Access fast-case object properties at index. The use of these routines
1451// is needed to correctly distinguish between properties stored in-object and
1452// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001453Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001454 // Adjust for the number of properties stored in the object.
1455 index -= map()->inobject_properties();
1456 if (index < 0) {
1457 int offset = map()->instance_size() + (index * kPointerSize);
1458 return READ_FIELD(this, offset);
1459 } else {
1460 ASSERT(index < properties()->length());
1461 return properties()->get(index);
1462 }
1463}
1464
1465
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001466Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001467 // Adjust for the number of properties stored in the object.
1468 index -= map()->inobject_properties();
1469 if (index < 0) {
1470 int offset = map()->instance_size() + (index * kPointerSize);
1471 WRITE_FIELD(this, offset, value);
1472 WRITE_BARRIER(this, offset);
1473 } else {
1474 ASSERT(index < properties()->length());
1475 properties()->set(index, value);
1476 }
1477 return value;
1478}
1479
1480
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001481int JSObject::GetInObjectPropertyOffset(int index) {
1482 // Adjust for the number of properties stored in the object.
1483 index -= map()->inobject_properties();
1484 ASSERT(index < 0);
1485 return map()->instance_size() + (index * kPointerSize);
1486}
1487
1488
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001489Object* JSObject::InObjectPropertyAt(int index) {
1490 // Adjust for the number of properties stored in the object.
1491 index -= map()->inobject_properties();
1492 ASSERT(index < 0);
1493 int offset = map()->instance_size() + (index * kPointerSize);
1494 return READ_FIELD(this, offset);
1495}
1496
1497
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001498Object* JSObject::InObjectPropertyAtPut(int index,
1499 Object* value,
1500 WriteBarrierMode mode) {
1501 // Adjust for the number of properties stored in the object.
1502 index -= map()->inobject_properties();
1503 ASSERT(index < 0);
1504 int offset = map()->instance_size() + (index * kPointerSize);
1505 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001506 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001507 return value;
1508}
1509
1510
1511
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001512void JSObject::InitializeBody(int object_size, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001513 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001514 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001515 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001516 }
1517}
1518
1519
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001520bool JSObject::HasFastProperties() {
1521 return !properties()->IsDictionary();
1522}
1523
1524
1525int JSObject::MaxFastProperties() {
1526 // Allow extra fast properties if the object has more than
1527 // kMaxFastProperties in-object properties. When this is the case,
1528 // it is very unlikely that the object is being used as a dictionary
1529 // and there is a good chance that allowing more map transitions
1530 // will be worth it.
1531 return Max(map()->inobject_properties(), kMaxFastProperties);
1532}
1533
1534
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001535void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001536 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001537 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001538 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001539 }
1540}
1541
1542
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001543bool Object::ToArrayIndex(uint32_t* index) {
1544 if (IsSmi()) {
1545 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001546 if (value < 0) return false;
1547 *index = value;
1548 return true;
1549 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001550 if (IsHeapNumber()) {
1551 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001552 uint32_t uint_value = static_cast<uint32_t>(value);
1553 if (value == static_cast<double>(uint_value)) {
1554 *index = uint_value;
1555 return true;
1556 }
1557 }
1558 return false;
1559}
1560
1561
1562bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1563 if (!this->IsJSValue()) return false;
1564
1565 JSValue* js_value = JSValue::cast(this);
1566 if (!js_value->value()->IsString()) return false;
1567
1568 String* str = String::cast(js_value->value());
1569 if (index >= (uint32_t)str->length()) return false;
1570
1571 return true;
1572}
1573
1574
1575Object* FixedArray::get(int index) {
1576 ASSERT(index >= 0 && index < this->length());
1577 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1578}
1579
1580
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001581void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001582 ASSERT(map() != HEAP->fixed_cow_array_map());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001583 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1584 int offset = kHeaderSize + index * kPointerSize;
1585 WRITE_FIELD(this, offset, value);
1586}
1587
1588
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001589void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001590 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001591 ASSERT(index >= 0 && index < this->length());
1592 int offset = kHeaderSize + index * kPointerSize;
1593 WRITE_FIELD(this, offset, value);
1594 WRITE_BARRIER(this, offset);
1595}
1596
1597
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001598WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001599 if (GetHeap()->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001600 return UPDATE_WRITE_BARRIER;
1601}
1602
1603
1604void FixedArray::set(int index,
1605 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001606 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001607 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001608 ASSERT(index >= 0 && index < this->length());
1609 int offset = kHeaderSize + index * kPointerSize;
1610 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001611 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001612}
1613
1614
1615void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001616 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001617 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001618 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001619 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1620}
1621
1622
1623void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001624 ASSERT(map() != HEAP->fixed_cow_array_map());
1625 set_undefined(GetHeap(), index);
1626}
1627
1628
1629void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001630 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001631 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001632 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001633 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001634}
1635
1636
ager@chromium.org236ad962008-09-25 09:45:57 +00001637void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001638 set_null(GetHeap(), index);
1639}
1640
1641
1642void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001643 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001644 ASSERT(!heap->InNewSpace(heap->null_value()));
1645 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001646}
1647
1648
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001649void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001650 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001651 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001652 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1653 WRITE_FIELD(this,
1654 kHeaderSize + index * kPointerSize,
1655 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001656}
1657
1658
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001659void FixedArray::set_unchecked(int index, Smi* value) {
1660 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1661 int offset = kHeaderSize + index * kPointerSize;
1662 WRITE_FIELD(this, offset, value);
1663}
1664
1665
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001666void FixedArray::set_unchecked(Heap* heap,
1667 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001668 Object* value,
1669 WriteBarrierMode mode) {
1670 int offset = kHeaderSize + index * kPointerSize;
1671 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001672 CONDITIONAL_WRITE_BARRIER(heap, this, offset, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001673}
1674
1675
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001676void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001677 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001678 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1679 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001680}
1681
1682
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001683Object** FixedArray::data_start() {
1684 return HeapObject::RawField(this, kHeaderSize);
1685}
1686
1687
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001688bool DescriptorArray::IsEmpty() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00001689 ASSERT(this->IsSmi() ||
1690 this->length() > kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001691 this == HEAP->empty_descriptor_array());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001692 return this->IsSmi() || length() <= kFirstIndex;
1693}
1694
1695
1696int DescriptorArray::bit_field3_storage() {
1697 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1698 return Smi::cast(storage)->value();
1699}
1700
1701void DescriptorArray::set_bit_field3_storage(int value) {
1702 ASSERT(!IsEmpty());
1703 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001704}
1705
1706
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001707void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1708 Object* tmp = array->get(first);
1709 fast_set(array, first, array->get(second));
1710 fast_set(array, second, tmp);
1711}
1712
1713
1714int DescriptorArray::Search(String* name) {
1715 SLOW_ASSERT(IsSortedNoDuplicates());
1716
1717 // Check for empty descriptor array.
1718 int nof = number_of_descriptors();
1719 if (nof == 0) return kNotFound;
1720
1721 // Fast case: do linear search for small arrays.
1722 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001723 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001724 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001725 }
1726
1727 // Slow case: perform binary search.
1728 return BinarySearch(name, 0, nof - 1);
1729}
1730
1731
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001732int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001733 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001734 if (number == DescriptorLookupCache::kAbsent) {
1735 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001736 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001737 }
1738 return number;
1739}
1740
1741
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001742String* DescriptorArray::GetKey(int descriptor_number) {
1743 ASSERT(descriptor_number < number_of_descriptors());
1744 return String::cast(get(ToKeyIndex(descriptor_number)));
1745}
1746
1747
1748Object* DescriptorArray::GetValue(int descriptor_number) {
1749 ASSERT(descriptor_number < number_of_descriptors());
1750 return GetContentArray()->get(ToValueIndex(descriptor_number));
1751}
1752
1753
1754Smi* DescriptorArray::GetDetails(int descriptor_number) {
1755 ASSERT(descriptor_number < number_of_descriptors());
1756 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1757}
1758
1759
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001760PropertyType DescriptorArray::GetType(int descriptor_number) {
1761 ASSERT(descriptor_number < number_of_descriptors());
1762 return PropertyDetails(GetDetails(descriptor_number)).type();
1763}
1764
1765
1766int DescriptorArray::GetFieldIndex(int descriptor_number) {
1767 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1768}
1769
1770
1771JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1772 return JSFunction::cast(GetValue(descriptor_number));
1773}
1774
1775
1776Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1777 ASSERT(GetType(descriptor_number) == CALLBACKS);
1778 return GetValue(descriptor_number);
1779}
1780
1781
1782AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1783 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001784 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
1785 return reinterpret_cast<AccessorDescriptor*>(p->address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001786}
1787
1788
1789bool DescriptorArray::IsProperty(int descriptor_number) {
1790 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1791}
1792
1793
1794bool DescriptorArray::IsTransition(int descriptor_number) {
1795 PropertyType t = GetType(descriptor_number);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001796 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION ||
1797 t == EXTERNAL_ARRAY_TRANSITION;
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001798}
1799
1800
1801bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1802 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1803}
1804
1805
1806bool DescriptorArray::IsDontEnum(int descriptor_number) {
1807 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1808}
1809
1810
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001811void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1812 desc->Init(GetKey(descriptor_number),
1813 GetValue(descriptor_number),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001814 PropertyDetails(GetDetails(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001815}
1816
1817
1818void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1819 // Range check.
1820 ASSERT(descriptor_number < number_of_descriptors());
1821
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001822 // Make sure none of the elements in desc are in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001823 ASSERT(!HEAP->InNewSpace(desc->GetKey()));
1824 ASSERT(!HEAP->InNewSpace(desc->GetValue()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001825
1826 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1827 FixedArray* content_array = GetContentArray();
1828 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1829 fast_set(content_array, ToDetailsIndex(descriptor_number),
1830 desc->GetDetails().AsSmi());
1831}
1832
1833
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001834void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1835 Descriptor desc;
1836 src->Get(src_index, &desc);
1837 Set(index, &desc);
1838}
1839
1840
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001841void DescriptorArray::Swap(int first, int second) {
1842 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1843 FixedArray* content_array = GetContentArray();
1844 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1845 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1846}
1847
1848
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001849template<typename Shape, typename Key>
1850int HashTable<Shape, Key>::FindEntry(Key key) {
1851 return FindEntry(GetIsolate(), key);
1852}
1853
1854
1855// Find entry for key otherwise return kNotFound.
1856template<typename Shape, typename Key>
1857int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
1858 uint32_t capacity = Capacity();
1859 uint32_t entry = FirstProbe(Shape::Hash(key), capacity);
1860 uint32_t count = 1;
1861 // EnsureCapacity will guarantee the hash table is never full.
1862 while (true) {
1863 Object* element = KeyAt(entry);
1864 if (element == isolate->heap()->undefined_value()) break; // Empty entry.
1865 if (element != isolate->heap()->null_value() &&
1866 Shape::IsMatch(key, element)) return entry;
1867 entry = NextProbe(entry, count++, capacity);
1868 }
1869 return kNotFound;
1870}
1871
1872
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001873bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001874 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001875 if (!max_index_object->IsSmi()) return false;
1876 return 0 !=
1877 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1878}
1879
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001880uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001881 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001882 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001883 if (!max_index_object->IsSmi()) return 0;
1884 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1885 return value >> kRequiresSlowElementsTagSize;
1886}
1887
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001888void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001889 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001890}
1891
1892
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001893// ------------------------------------
1894// Cast operations
1895
1896
1897CAST_ACCESSOR(FixedArray)
1898CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001899CAST_ACCESSOR(DeoptimizationInputData)
1900CAST_ACCESSOR(DeoptimizationOutputData)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001901CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00001902CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00001903CAST_ACCESSOR(NormalizedMapCache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00001904CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001905CAST_ACCESSOR(CodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00001906CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001907CAST_ACCESSOR(String)
1908CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00001909CAST_ACCESSOR(SeqAsciiString)
1910CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001911CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001912CAST_ACCESSOR(ExternalString)
1913CAST_ACCESSOR(ExternalAsciiString)
1914CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001915CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001916CAST_ACCESSOR(JSObject)
1917CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001918CAST_ACCESSOR(HeapObject)
1919CAST_ACCESSOR(HeapNumber)
1920CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001921CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001922CAST_ACCESSOR(SharedFunctionInfo)
1923CAST_ACCESSOR(Map)
1924CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001925CAST_ACCESSOR(GlobalObject)
1926CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001927CAST_ACCESSOR(JSGlobalObject)
1928CAST_ACCESSOR(JSBuiltinsObject)
1929CAST_ACCESSOR(Code)
1930CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00001931CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00001932CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001933CAST_ACCESSOR(JSFunctionProxy)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001934CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001935CAST_ACCESSOR(ByteArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00001936CAST_ACCESSOR(ExternalArray)
1937CAST_ACCESSOR(ExternalByteArray)
1938CAST_ACCESSOR(ExternalUnsignedByteArray)
1939CAST_ACCESSOR(ExternalShortArray)
1940CAST_ACCESSOR(ExternalUnsignedShortArray)
1941CAST_ACCESSOR(ExternalIntArray)
1942CAST_ACCESSOR(ExternalUnsignedIntArray)
1943CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00001944CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001945CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001946CAST_ACCESSOR(Struct)
1947
1948
1949#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
1950 STRUCT_LIST(MAKE_STRUCT_CAST)
1951#undef MAKE_STRUCT_CAST
1952
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001953
1954template <typename Shape, typename Key>
1955HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001956 ASSERT(obj->IsHashTable());
1957 return reinterpret_cast<HashTable*>(obj);
1958}
1959
1960
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001961SMI_ACCESSORS(FixedArray, length, kLengthOffset)
1962SMI_ACCESSORS(ByteArray, length, kLengthOffset)
1963
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001964INT_ACCESSORS(ExternalArray, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001965
1966
ager@chromium.orgac091b72010-05-05 07:34:42 +00001967SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001968
1969
1970uint32_t String::hash_field() {
1971 return READ_UINT32_FIELD(this, kHashFieldOffset);
1972}
1973
1974
1975void String::set_hash_field(uint32_t value) {
1976 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001977#if V8_HOST_ARCH_64_BIT
1978 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
1979#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001980}
1981
1982
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001983bool String::Equals(String* other) {
1984 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001985 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
1986 return false;
1987 }
1988 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001989}
1990
1991
lrn@chromium.org303ada72010-10-27 09:33:13 +00001992MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001993 if (!StringShape(this).IsCons()) return this;
1994 ConsString* cons = ConsString::cast(this);
1995 if (cons->second()->length() == 0) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001996 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001997}
1998
1999
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002000String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002001 MaybeObject* flat = TryFlatten(pretenure);
2002 Object* successfully_flattened;
2003 if (flat->ToObject(&successfully_flattened)) {
2004 return String::cast(successfully_flattened);
2005 }
2006 return this;
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002007}
2008
2009
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002010uint16_t String::Get(int index) {
2011 ASSERT(index >= 0 && index < length());
2012 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002013 case kSeqStringTag | kAsciiStringTag:
2014 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2015 case kSeqStringTag | kTwoByteStringTag:
2016 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2017 case kConsStringTag | kAsciiStringTag:
2018 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002019 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002020 case kExternalStringTag | kAsciiStringTag:
2021 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2022 case kExternalStringTag | kTwoByteStringTag:
2023 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002024 default:
2025 break;
2026 }
2027
2028 UNREACHABLE();
2029 return 0;
2030}
2031
2032
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002033void String::Set(int index, uint16_t value) {
2034 ASSERT(index >= 0 && index < length());
2035 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002036
ager@chromium.org5ec48922009-05-05 07:25:34 +00002037 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002038 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2039 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002040}
2041
2042
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002043bool String::IsFlat() {
2044 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002045 case kConsStringTag: {
2046 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00002047 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00002048 return second->length() == 0;
2049 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00002050 default:
2051 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002052 }
2053}
2054
2055
ager@chromium.org7c537e22008-10-16 08:43:32 +00002056uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002057 ASSERT(index >= 0 && index < length());
2058 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2059}
2060
2061
ager@chromium.org7c537e22008-10-16 08:43:32 +00002062void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002063 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2064 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2065 static_cast<byte>(value));
2066}
2067
2068
ager@chromium.org7c537e22008-10-16 08:43:32 +00002069Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002070 return FIELD_ADDR(this, kHeaderSize);
2071}
2072
2073
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002074char* SeqAsciiString::GetChars() {
2075 return reinterpret_cast<char*>(GetCharsAddress());
2076}
2077
2078
ager@chromium.org7c537e22008-10-16 08:43:32 +00002079Address SeqTwoByteString::GetCharsAddress() {
2080 return FIELD_ADDR(this, kHeaderSize);
2081}
2082
2083
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002084uc16* SeqTwoByteString::GetChars() {
2085 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2086}
2087
2088
ager@chromium.org7c537e22008-10-16 08:43:32 +00002089uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002090 ASSERT(index >= 0 && index < length());
2091 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2092}
2093
2094
ager@chromium.org7c537e22008-10-16 08:43:32 +00002095void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002096 ASSERT(index >= 0 && index < length());
2097 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2098}
2099
2100
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002101int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002102 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002103}
2104
2105
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002106int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002107 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002108}
2109
2110
ager@chromium.org870a0b62008-11-04 11:43:05 +00002111String* ConsString::first() {
2112 return String::cast(READ_FIELD(this, kFirstOffset));
2113}
2114
2115
2116Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002117 return READ_FIELD(this, kFirstOffset);
2118}
2119
2120
ager@chromium.org870a0b62008-11-04 11:43:05 +00002121void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002122 WRITE_FIELD(this, kFirstOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002123 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002124}
2125
2126
ager@chromium.org870a0b62008-11-04 11:43:05 +00002127String* ConsString::second() {
2128 return String::cast(READ_FIELD(this, kSecondOffset));
2129}
2130
2131
2132Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002133 return READ_FIELD(this, kSecondOffset);
2134}
2135
2136
ager@chromium.org870a0b62008-11-04 11:43:05 +00002137void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002138 WRITE_FIELD(this, kSecondOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002139 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002140}
2141
2142
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002143ExternalAsciiString::Resource* ExternalAsciiString::resource() {
2144 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2145}
2146
2147
2148void ExternalAsciiString::set_resource(
2149 ExternalAsciiString::Resource* resource) {
2150 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2151}
2152
2153
2154ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
2155 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2156}
2157
2158
2159void ExternalTwoByteString::set_resource(
2160 ExternalTwoByteString::Resource* resource) {
2161 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2162}
2163
2164
ager@chromium.orgac091b72010-05-05 07:34:42 +00002165void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002166 set_finger_index(kEntriesIndex);
2167 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002168}
2169
2170
2171void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002172 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002173 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002174 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002175 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002176 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002177 MakeZeroSize();
2178}
2179
2180
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002181int JSFunctionResultCache::size() {
2182 return Smi::cast(get(kCacheSizeIndex))->value();
2183}
2184
2185
2186void JSFunctionResultCache::set_size(int size) {
2187 set(kCacheSizeIndex, Smi::FromInt(size));
2188}
2189
2190
2191int JSFunctionResultCache::finger_index() {
2192 return Smi::cast(get(kFingerIndex))->value();
2193}
2194
2195
2196void JSFunctionResultCache::set_finger_index(int finger_index) {
2197 set(kFingerIndex, Smi::FromInt(finger_index));
2198}
2199
2200
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002201byte ByteArray::get(int index) {
2202 ASSERT(index >= 0 && index < this->length());
2203 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2204}
2205
2206
2207void ByteArray::set(int index, byte value) {
2208 ASSERT(index >= 0 && index < this->length());
2209 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2210}
2211
2212
2213int ByteArray::get_int(int index) {
2214 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2215 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2216}
2217
2218
2219ByteArray* ByteArray::FromDataStartAddress(Address address) {
2220 ASSERT_TAG_ALIGNED(address);
2221 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2222}
2223
2224
2225Address ByteArray::GetDataStartAddress() {
2226 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2227}
2228
2229
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002230uint8_t* ExternalPixelArray::external_pixel_pointer() {
2231 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002232}
2233
2234
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002235uint8_t ExternalPixelArray::get(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002236 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002237 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002238 return ptr[index];
2239}
2240
2241
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002242void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002243 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002244 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002245 ptr[index] = value;
2246}
2247
2248
ager@chromium.org3811b432009-10-28 14:53:37 +00002249void* ExternalArray::external_pointer() {
2250 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2251 return reinterpret_cast<void*>(ptr);
2252}
2253
2254
2255void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2256 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2257 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2258}
2259
2260
2261int8_t ExternalByteArray::get(int index) {
2262 ASSERT((index >= 0) && (index < this->length()));
2263 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2264 return ptr[index];
2265}
2266
2267
2268void ExternalByteArray::set(int index, int8_t value) {
2269 ASSERT((index >= 0) && (index < this->length()));
2270 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2271 ptr[index] = value;
2272}
2273
2274
2275uint8_t ExternalUnsignedByteArray::get(int index) {
2276 ASSERT((index >= 0) && (index < this->length()));
2277 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2278 return ptr[index];
2279}
2280
2281
2282void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2283 ASSERT((index >= 0) && (index < this->length()));
2284 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2285 ptr[index] = value;
2286}
2287
2288
2289int16_t ExternalShortArray::get(int index) {
2290 ASSERT((index >= 0) && (index < this->length()));
2291 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2292 return ptr[index];
2293}
2294
2295
2296void ExternalShortArray::set(int index, int16_t value) {
2297 ASSERT((index >= 0) && (index < this->length()));
2298 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2299 ptr[index] = value;
2300}
2301
2302
2303uint16_t ExternalUnsignedShortArray::get(int index) {
2304 ASSERT((index >= 0) && (index < this->length()));
2305 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2306 return ptr[index];
2307}
2308
2309
2310void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2311 ASSERT((index >= 0) && (index < this->length()));
2312 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2313 ptr[index] = value;
2314}
2315
2316
2317int32_t ExternalIntArray::get(int index) {
2318 ASSERT((index >= 0) && (index < this->length()));
2319 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2320 return ptr[index];
2321}
2322
2323
2324void ExternalIntArray::set(int index, int32_t value) {
2325 ASSERT((index >= 0) && (index < this->length()));
2326 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2327 ptr[index] = value;
2328}
2329
2330
2331uint32_t ExternalUnsignedIntArray::get(int index) {
2332 ASSERT((index >= 0) && (index < this->length()));
2333 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2334 return ptr[index];
2335}
2336
2337
2338void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2339 ASSERT((index >= 0) && (index < this->length()));
2340 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2341 ptr[index] = value;
2342}
2343
2344
2345float ExternalFloatArray::get(int index) {
2346 ASSERT((index >= 0) && (index < this->length()));
2347 float* ptr = static_cast<float*>(external_pointer());
2348 return ptr[index];
2349}
2350
2351
2352void ExternalFloatArray::set(int index, float value) {
2353 ASSERT((index >= 0) && (index < this->length()));
2354 float* ptr = static_cast<float*>(external_pointer());
2355 ptr[index] = value;
2356}
2357
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002358
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002359double ExternalDoubleArray::get(int index) {
2360 ASSERT((index >= 0) && (index < this->length()));
2361 double* ptr = static_cast<double*>(external_pointer());
2362 return ptr[index];
2363}
2364
2365
2366void ExternalDoubleArray::set(int index, double value) {
2367 ASSERT((index >= 0) && (index < this->length()));
2368 double* ptr = static_cast<double*>(external_pointer());
2369 ptr[index] = value;
2370}
2371
2372
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002373int Map::visitor_id() {
2374 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2375}
2376
2377
2378void Map::set_visitor_id(int id) {
2379 ASSERT(0 <= id && id < 256);
2380 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2381}
2382
ager@chromium.org3811b432009-10-28 14:53:37 +00002383
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002384int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002385 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2386}
2387
2388
2389int Map::inobject_properties() {
2390 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002391}
2392
2393
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002394int Map::pre_allocated_property_fields() {
2395 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2396}
2397
2398
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002399int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002400 int instance_size = map->instance_size();
2401 if (instance_size != kVariableSizeSentinel) return instance_size;
2402 // We can ignore the "symbol" bit becase it is only set for symbols
2403 // and implies a string type.
2404 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002405 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002406 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002407 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002408 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002409 if (instance_type == ASCII_STRING_TYPE) {
2410 return SeqAsciiString::SizeFor(
2411 reinterpret_cast<SeqAsciiString*>(this)->length());
2412 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002413 if (instance_type == BYTE_ARRAY_TYPE) {
2414 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2415 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002416 if (instance_type == STRING_TYPE) {
2417 return SeqTwoByteString::SizeFor(
2418 reinterpret_cast<SeqTwoByteString*>(this)->length());
2419 }
2420 ASSERT(instance_type == CODE_TYPE);
2421 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002422}
2423
2424
2425void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002426 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002427 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002428 ASSERT(0 <= value && value < 256);
2429 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2430}
2431
2432
ager@chromium.org7c537e22008-10-16 08:43:32 +00002433void Map::set_inobject_properties(int value) {
2434 ASSERT(0 <= value && value < 256);
2435 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2436}
2437
2438
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002439void Map::set_pre_allocated_property_fields(int value) {
2440 ASSERT(0 <= value && value < 256);
2441 WRITE_BYTE_FIELD(this,
2442 kPreAllocatedPropertyFieldsOffset,
2443 static_cast<byte>(value));
2444}
2445
2446
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002447InstanceType Map::instance_type() {
2448 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2449}
2450
2451
2452void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002453 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2454}
2455
2456
2457int Map::unused_property_fields() {
2458 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2459}
2460
2461
2462void Map::set_unused_property_fields(int value) {
2463 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2464}
2465
2466
2467byte Map::bit_field() {
2468 return READ_BYTE_FIELD(this, kBitFieldOffset);
2469}
2470
2471
2472void Map::set_bit_field(byte value) {
2473 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2474}
2475
2476
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002477byte Map::bit_field2() {
2478 return READ_BYTE_FIELD(this, kBitField2Offset);
2479}
2480
2481
2482void Map::set_bit_field2(byte value) {
2483 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2484}
2485
2486
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002487void Map::set_non_instance_prototype(bool value) {
2488 if (value) {
2489 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2490 } else {
2491 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2492 }
2493}
2494
2495
2496bool Map::has_non_instance_prototype() {
2497 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2498}
2499
2500
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002501void Map::set_function_with_prototype(bool value) {
2502 if (value) {
2503 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2504 } else {
2505 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2506 }
2507}
2508
2509
2510bool Map::function_with_prototype() {
2511 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2512}
2513
2514
ager@chromium.org870a0b62008-11-04 11:43:05 +00002515void Map::set_is_access_check_needed(bool access_check_needed) {
2516 if (access_check_needed) {
2517 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2518 } else {
2519 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2520 }
2521}
2522
2523
2524bool Map::is_access_check_needed() {
2525 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2526}
2527
2528
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002529void Map::set_is_extensible(bool value) {
2530 if (value) {
2531 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2532 } else {
2533 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2534 }
2535}
2536
2537bool Map::is_extensible() {
2538 return ((1 << kIsExtensible) & bit_field2()) != 0;
2539}
2540
2541
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002542void Map::set_attached_to_shared_function_info(bool value) {
2543 if (value) {
2544 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2545 } else {
2546 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2547 }
2548}
2549
2550bool Map::attached_to_shared_function_info() {
2551 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2552}
2553
2554
2555void Map::set_is_shared(bool value) {
2556 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002557 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002558 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002559 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002560 }
2561}
2562
2563bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002564 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002565}
2566
2567
2568JSFunction* Map::unchecked_constructor() {
2569 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2570}
2571
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002572
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002573FixedArray* Map::unchecked_prototype_transitions() {
2574 return reinterpret_cast<FixedArray*>(
2575 READ_FIELD(this, kPrototypeTransitionsOffset));
2576}
2577
2578
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002579Code::Flags Code::flags() {
2580 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2581}
2582
2583
2584void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002585 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002586 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002587 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2588 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002589 ExtractArgumentsCountFromFlags(flags) >= 0);
2590 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2591}
2592
2593
2594Code::Kind Code::kind() {
2595 return ExtractKindFromFlags(flags());
2596}
2597
2598
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002599InLoopFlag Code::ic_in_loop() {
2600 return ExtractICInLoopFromFlags(flags());
2601}
2602
2603
kasper.lund7276f142008-07-30 08:49:36 +00002604InlineCacheState Code::ic_state() {
2605 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002606 // Only allow uninitialized or debugger states for non-IC code
2607 // objects. This is used in the debugger to determine whether or not
2608 // a call to code object has been replaced with a debug break call.
2609 ASSERT(is_inline_cache_stub() ||
2610 result == UNINITIALIZED ||
2611 result == DEBUG_BREAK ||
2612 result == DEBUG_PREPARE_STEP_IN);
2613 return result;
2614}
2615
2616
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002617Code::ExtraICState Code::extra_ic_state() {
2618 ASSERT(is_inline_cache_stub());
2619 return ExtractExtraICStateFromFlags(flags());
2620}
2621
2622
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002623PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002624 return ExtractTypeFromFlags(flags());
2625}
2626
2627
2628int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002629 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002630 return ExtractArgumentsCountFromFlags(flags());
2631}
2632
2633
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002634int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002635 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002636 kind() == UNARY_OP_IC ||
2637 kind() == BINARY_OP_IC ||
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002638 kind() == COMPARE_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002639 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002640}
2641
2642
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002643void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002644 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002645 kind() == UNARY_OP_IC ||
2646 kind() == BINARY_OP_IC ||
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002647 kind() == COMPARE_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002648 ASSERT(0 <= major && major < 256);
2649 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002650}
2651
2652
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002653bool Code::optimizable() {
2654 ASSERT(kind() == FUNCTION);
2655 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2656}
2657
2658
2659void Code::set_optimizable(bool value) {
2660 ASSERT(kind() == FUNCTION);
2661 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2662}
2663
2664
2665bool Code::has_deoptimization_support() {
2666 ASSERT(kind() == FUNCTION);
2667 return READ_BYTE_FIELD(this, kHasDeoptimizationSupportOffset) == 1;
2668}
2669
2670
2671void Code::set_has_deoptimization_support(bool value) {
2672 ASSERT(kind() == FUNCTION);
2673 WRITE_BYTE_FIELD(this, kHasDeoptimizationSupportOffset, value ? 1 : 0);
2674}
2675
2676
2677int Code::allow_osr_at_loop_nesting_level() {
2678 ASSERT(kind() == FUNCTION);
2679 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
2680}
2681
2682
2683void Code::set_allow_osr_at_loop_nesting_level(int level) {
2684 ASSERT(kind() == FUNCTION);
2685 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
2686 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
2687}
2688
2689
2690unsigned Code::stack_slots() {
2691 ASSERT(kind() == OPTIMIZED_FUNCTION);
2692 return READ_UINT32_FIELD(this, kStackSlotsOffset);
2693}
2694
2695
2696void Code::set_stack_slots(unsigned slots) {
2697 ASSERT(kind() == OPTIMIZED_FUNCTION);
2698 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
2699}
2700
2701
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002702unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002703 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002704 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002705}
2706
2707
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002708void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002709 ASSERT(kind() == OPTIMIZED_FUNCTION);
2710 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002711 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002712}
2713
2714
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002715unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002716 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002717 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002718}
2719
2720
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002721void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002722 ASSERT(kind() == FUNCTION);
2723 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002724 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002725}
2726
2727
2728CheckType Code::check_type() {
2729 ASSERT(is_call_stub() || is_keyed_call_stub());
2730 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
2731 return static_cast<CheckType>(type);
2732}
2733
2734
2735void Code::set_check_type(CheckType value) {
2736 ASSERT(is_call_stub() || is_keyed_call_stub());
2737 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
2738}
2739
2740
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002741ExternalArrayType Code::external_array_type() {
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002742 ASSERT(is_keyed_load_stub() || is_keyed_store_stub());
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002743 byte type = READ_BYTE_FIELD(this, kExternalArrayTypeOffset);
2744 return static_cast<ExternalArrayType>(type);
2745}
2746
2747
2748void Code::set_external_array_type(ExternalArrayType value) {
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002749 ASSERT(is_keyed_load_stub() || is_keyed_store_stub());
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002750 WRITE_BYTE_FIELD(this, kExternalArrayTypeOffset, value);
2751}
2752
2753
danno@chromium.org40cb8782011-05-25 07:58:50 +00002754byte Code::unary_op_type() {
2755 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002756 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
2757}
2758
2759
danno@chromium.org40cb8782011-05-25 07:58:50 +00002760void Code::set_unary_op_type(byte value) {
2761 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002762 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
2763}
2764
2765
danno@chromium.org40cb8782011-05-25 07:58:50 +00002766byte Code::binary_op_type() {
2767 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002768 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
2769}
2770
2771
danno@chromium.org40cb8782011-05-25 07:58:50 +00002772void Code::set_binary_op_type(byte value) {
2773 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002774 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
2775}
2776
2777
danno@chromium.org40cb8782011-05-25 07:58:50 +00002778byte Code::binary_op_result_type() {
2779 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002780 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
2781}
2782
2783
danno@chromium.org40cb8782011-05-25 07:58:50 +00002784void Code::set_binary_op_result_type(byte value) {
2785 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002786 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
2787}
2788
2789
2790byte Code::compare_state() {
2791 ASSERT(is_compare_ic_stub());
2792 return READ_BYTE_FIELD(this, kCompareStateOffset);
2793}
2794
2795
2796void Code::set_compare_state(byte value) {
2797 ASSERT(is_compare_ic_stub());
2798 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
2799}
2800
2801
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002802bool Code::is_inline_cache_stub() {
2803 Kind kind = this->kind();
2804 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2805}
2806
2807
2808Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002809 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002810 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002811 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002812 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002813 int argc,
2814 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002815 // Extra IC state is only allowed for call IC stubs or for store IC
2816 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002817 ASSERT(extra_ic_state == kNoExtraICState ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002818 (kind == CALL_IC) ||
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00002819 (kind == STORE_IC) ||
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002820 (kind == KEYED_STORE_IC));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002821 // Compute the bit mask.
2822 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002823 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002824 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002825 bits |= type << kFlagsTypeShift;
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002826 bits |= extra_ic_state << kFlagsExtraICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002827 bits |= argc << kFlagsArgumentsCountShift;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002828 if (holder == PROTOTYPE_MAP) bits |= kFlagsCacheInPrototypeMapMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002829 // Cast to flags and validate result before returning it.
2830 Flags result = static_cast<Flags>(bits);
2831 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002832 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002833 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002834 ASSERT(ExtractTypeFromFlags(result) == type);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002835 ASSERT(ExtractExtraICStateFromFlags(result) == extra_ic_state);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002836 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2837 return result;
2838}
2839
2840
2841Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2842 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002843 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002844 InlineCacheHolderFlag holder,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002845 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002846 int argc) {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002847 return ComputeFlags(
2848 kind, in_loop, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002849}
2850
2851
2852Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2853 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2854 return static_cast<Kind>(bits);
2855}
2856
2857
kasper.lund7276f142008-07-30 08:49:36 +00002858InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2859 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002860 return static_cast<InlineCacheState>(bits);
2861}
2862
2863
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002864Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
2865 int bits = (flags & kFlagsExtraICStateMask) >> kFlagsExtraICStateShift;
2866 return static_cast<ExtraICState>(bits);
2867}
2868
2869
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002870InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2871 int bits = (flags & kFlagsICInLoopMask);
2872 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2873}
2874
2875
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002876PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2877 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2878 return static_cast<PropertyType>(bits);
2879}
2880
2881
2882int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2883 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2884}
2885
2886
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002887InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
2888 int bits = (flags & kFlagsCacheInPrototypeMapMask);
2889 return bits != 0 ? PROTOTYPE_MAP : OWN_MAP;
2890}
2891
2892
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002893Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2894 int bits = flags & ~kFlagsTypeMask;
2895 return static_cast<Flags>(bits);
2896}
2897
2898
ager@chromium.org8bb60582008-12-11 12:02:20 +00002899Code* Code::GetCodeFromTargetAddress(Address address) {
2900 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2901 // GetCodeFromTargetAddress might be called when marking objects during mark
2902 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2903 // Code::cast. Code::cast does not work when the object's map is
2904 // marked.
2905 Code* result = reinterpret_cast<Code*>(code);
2906 return result;
2907}
2908
2909
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002910Isolate* Map::isolate() {
2911 return heap()->isolate();
2912}
2913
2914
2915Heap* Map::heap() {
2916 // NOTE: address() helper is not used to save one instruction.
2917 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
2918 ASSERT(heap != NULL);
2919 ASSERT(heap->isolate() == Isolate::Current());
2920 return heap;
2921}
2922
2923
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002924Heap* Code::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* Code::isolate() {
2934 return heap()->isolate();
2935}
2936
2937
2938Heap* JSGlobalPropertyCell::heap() {
2939 // NOTE: address() helper is not used to save one instruction.
2940 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
2941 ASSERT(heap != NULL);
2942 ASSERT(heap->isolate() == Isolate::Current());
2943 return heap;
2944}
2945
2946
2947Isolate* JSGlobalPropertyCell::isolate() {
2948 return heap()->isolate();
2949}
2950
2951
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002952Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
2953 return HeapObject::
2954 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
2955}
2956
2957
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002958Object* Map::prototype() {
2959 return READ_FIELD(this, kPrototypeOffset);
2960}
2961
2962
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002963void Map::set_prototype(Object* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002964 ASSERT(value->IsNull() || value->IsJSObject());
2965 WRITE_FIELD(this, kPrototypeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002966 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002967}
2968
2969
lrn@chromium.org303ada72010-10-27 09:33:13 +00002970MaybeObject* Map::GetFastElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002971 if (has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00002972 Object* obj;
2973 { MaybeObject* maybe_obj = CopyDropTransitions();
2974 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2975 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002976 Map* new_map = Map::cast(obj);
2977 new_map->set_has_fast_elements(true);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002978 isolate()->counters()->map_slow_to_fast_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002979 return new_map;
2980}
2981
2982
lrn@chromium.org303ada72010-10-27 09:33:13 +00002983MaybeObject* Map::GetSlowElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002984 if (!has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00002985 Object* obj;
2986 { MaybeObject* maybe_obj = CopyDropTransitions();
2987 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2988 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002989 Map* new_map = Map::cast(obj);
2990 new_map->set_has_fast_elements(false);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002991 isolate()->counters()->map_fast_to_slow_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002992 return new_map;
2993}
2994
2995
danno@chromium.org40cb8782011-05-25 07:58:50 +00002996DescriptorArray* Map::instance_descriptors() {
2997 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
2998 if (object->IsSmi()) {
2999 return HEAP->empty_descriptor_array();
3000 } else {
3001 return DescriptorArray::cast(object);
3002 }
3003}
3004
3005
3006void Map::init_instance_descriptors() {
3007 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3008}
3009
3010
3011void Map::clear_instance_descriptors() {
3012 Object* object = READ_FIELD(this,
3013 kInstanceDescriptorsOrBitField3Offset);
3014 if (!object->IsSmi()) {
3015 WRITE_FIELD(
3016 this,
3017 kInstanceDescriptorsOrBitField3Offset,
3018 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3019 }
3020}
3021
3022
3023void Map::set_instance_descriptors(DescriptorArray* value,
3024 WriteBarrierMode mode) {
3025 Object* object = READ_FIELD(this,
3026 kInstanceDescriptorsOrBitField3Offset);
3027 if (value == isolate()->heap()->empty_descriptor_array()) {
3028 clear_instance_descriptors();
3029 return;
3030 } else {
3031 if (object->IsSmi()) {
3032 value->set_bit_field3_storage(Smi::cast(object)->value());
3033 } else {
3034 value->set_bit_field3_storage(
3035 DescriptorArray::cast(object)->bit_field3_storage());
3036 }
3037 }
3038 ASSERT(!is_shared());
3039 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
3040 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3041 this,
3042 kInstanceDescriptorsOrBitField3Offset,
3043 mode);
3044}
3045
3046
3047int Map::bit_field3() {
3048 Object* object = READ_FIELD(this,
3049 kInstanceDescriptorsOrBitField3Offset);
3050 if (object->IsSmi()) {
3051 return Smi::cast(object)->value();
3052 } else {
3053 return DescriptorArray::cast(object)->bit_field3_storage();
3054 }
3055}
3056
3057
3058void Map::set_bit_field3(int value) {
3059 ASSERT(Smi::IsValid(value));
3060 Object* object = READ_FIELD(this,
3061 kInstanceDescriptorsOrBitField3Offset);
3062 if (object->IsSmi()) {
3063 WRITE_FIELD(this,
3064 kInstanceDescriptorsOrBitField3Offset,
3065 Smi::FromInt(value));
3066 } else {
3067 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3068 }
3069}
3070
3071
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003072ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003073ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003074ACCESSORS(Map, constructor, Object, kConstructorOffset)
3075
3076ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
3077ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003078ACCESSORS_GCSAFE(JSFunction, next_function_link, Object,
3079 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003080
3081ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3082ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003083ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003084
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003085ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003086
3087ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3088ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3089ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3090ACCESSORS(AccessorInfo, name, Object, kNameOffset)
3091ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
3092
3093ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3094ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3095ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3096
3097ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3098ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3099ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3100ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3101ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3102ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3103
3104ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3105ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3106
3107ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3108ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3109
3110ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3111ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003112ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3113 kPropertyAccessorsOffset)
3114ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3115 kPrototypeTemplateOffset)
3116ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3117ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3118 kNamedPropertyHandlerOffset)
3119ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3120 kIndexedPropertyHandlerOffset)
3121ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3122 kInstanceTemplateOffset)
3123ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3124ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003125ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3126 kInstanceCallHandlerOffset)
3127ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3128 kAccessCheckInfoOffset)
3129ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
3130
3131ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003132ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3133 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003134
3135ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3136ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3137
3138ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3139
3140ACCESSORS(Script, source, Object, kSourceOffset)
3141ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003142ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003143ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3144ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003145ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003146ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003147ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003148ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003149ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003150ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003151ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003152ACCESSORS(Script, eval_from_instructions_offset, Smi,
3153 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003154
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003155#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003156ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3157ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3158ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3159ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3160
3161ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3162ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3163ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3164ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003165#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003166
3167ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003168ACCESSORS_GCSAFE(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3169ACCESSORS_GCSAFE(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003170ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3171 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003172ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003173ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3174ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003175ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003176ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3177 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003178
3179BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3180 kHiddenPrototypeBit)
3181BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3182BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3183 kNeedsAccessCheckBit)
3184BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3185 kIsExpressionBit)
3186BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3187 kIsTopLevelBit)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003188BOOL_GETTER(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003189 has_only_simple_this_property_assignments,
3190 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003191BOOL_ACCESSORS(SharedFunctionInfo,
3192 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003193 allows_lazy_compilation,
3194 kAllowLazyCompilation)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003195
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003196
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003197#if V8_HOST_ARCH_32_BIT
3198SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3199SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003200 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003201SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003202 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003203SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3204SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003205 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003206SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3207SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003208 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003209SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003210 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003211SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003212 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003213SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003214#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003215
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003216#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003217 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003218 int holder::name() { \
3219 int value = READ_INT_FIELD(this, offset); \
3220 ASSERT(kHeapObjectTag == 1); \
3221 ASSERT((value & kHeapObjectTag) == 0); \
3222 return value >> 1; \
3223 } \
3224 void holder::set_##name(int value) { \
3225 ASSERT(kHeapObjectTag == 1); \
3226 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3227 (value & 0xC0000000) == 0x000000000); \
3228 WRITE_INT_FIELD(this, \
3229 offset, \
3230 (value << 1) & ~kHeapObjectTag); \
3231 }
3232
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003233#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3234 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003235 INT_ACCESSORS(holder, name, offset)
3236
3237
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003238PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003239PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3240 formal_parameter_count,
3241 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003242
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003243PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3244 expected_nof_properties,
3245 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003246PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3247
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003248PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3249PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3250 start_position_and_type,
3251 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003252
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003253PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3254 function_token_position,
3255 kFunctionTokenPositionOffset)
3256PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3257 compiler_hints,
3258 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003259
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003260PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3261 this_property_assignments_count,
3262 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003263PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003264#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003265
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003266
3267int SharedFunctionInfo::construction_count() {
3268 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3269}
3270
3271
3272void SharedFunctionInfo::set_construction_count(int value) {
3273 ASSERT(0 <= value && value < 256);
3274 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3275}
3276
3277
3278bool SharedFunctionInfo::live_objects_may_exist() {
3279 return (compiler_hints() & (1 << kLiveObjectsMayExist)) != 0;
3280}
3281
3282
3283void SharedFunctionInfo::set_live_objects_may_exist(bool value) {
3284 if (value) {
3285 set_compiler_hints(compiler_hints() | (1 << kLiveObjectsMayExist));
3286 } else {
3287 set_compiler_hints(compiler_hints() & ~(1 << kLiveObjectsMayExist));
3288 }
3289}
3290
3291
3292bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003293 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003294}
3295
3296
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003297bool SharedFunctionInfo::optimization_disabled() {
3298 return BooleanBit::get(compiler_hints(), kOptimizationDisabled);
3299}
3300
3301
3302void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3303 set_compiler_hints(BooleanBit::set(compiler_hints(),
3304 kOptimizationDisabled,
3305 disable));
3306 // If disabling optimizations we reflect that in the code object so
3307 // it will not be counted as optimizable code.
3308 if ((code()->kind() == Code::FUNCTION) && disable) {
3309 code()->set_optimizable(false);
3310 }
3311}
3312
3313
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003314bool SharedFunctionInfo::strict_mode() {
3315 return BooleanBit::get(compiler_hints(), kStrictModeFunction);
3316}
3317
3318
3319void SharedFunctionInfo::set_strict_mode(bool value) {
3320 set_compiler_hints(BooleanBit::set(compiler_hints(),
3321 kStrictModeFunction,
3322 value));
3323}
3324
3325
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00003326bool SharedFunctionInfo::native() {
3327 return BooleanBit::get(compiler_hints(), kNative);
ricow@chromium.org6fe7a8e2011-05-13 07:57:29 +00003328}
3329
3330
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00003331void SharedFunctionInfo::set_native(bool value) {
ricow@chromium.org6fe7a8e2011-05-13 07:57:29 +00003332 set_compiler_hints(BooleanBit::set(compiler_hints(),
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00003333 kNative,
ricow@chromium.org6fe7a8e2011-05-13 07:57:29 +00003334 value));
3335}
3336
3337
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003338ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3339ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3340
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003341bool Script::HasValidSource() {
3342 Object* src = this->source();
3343 if (!src->IsString()) return true;
3344 String* src_str = String::cast(src);
3345 if (!StringShape(src_str).IsExternal()) return true;
3346 if (src_str->IsAsciiRepresentation()) {
3347 return ExternalAsciiString::cast(src)->resource() != NULL;
3348 } else if (src_str->IsTwoByteRepresentation()) {
3349 return ExternalTwoByteString::cast(src)->resource() != NULL;
3350 }
3351 return true;
3352}
3353
3354
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003355void SharedFunctionInfo::DontAdaptArguments() {
3356 ASSERT(code()->kind() == Code::BUILTIN);
3357 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3358}
3359
3360
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003361int SharedFunctionInfo::start_position() {
3362 return start_position_and_type() >> kStartPositionShift;
3363}
3364
3365
3366void SharedFunctionInfo::set_start_position(int start_position) {
3367 set_start_position_and_type((start_position << kStartPositionShift)
3368 | (start_position_and_type() & ~kStartPositionMask));
3369}
3370
3371
3372Code* SharedFunctionInfo::code() {
3373 return Code::cast(READ_FIELD(this, kCodeOffset));
3374}
3375
3376
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003377Code* SharedFunctionInfo::unchecked_code() {
3378 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3379}
3380
3381
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003382void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003383 WRITE_FIELD(this, kCodeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003384 ASSERT(!Isolate::Current()->heap()->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003385}
3386
3387
ager@chromium.orgb5737492010-07-15 09:29:43 +00003388SerializedScopeInfo* SharedFunctionInfo::scope_info() {
3389 return reinterpret_cast<SerializedScopeInfo*>(
3390 READ_FIELD(this, kScopeInfoOffset));
3391}
3392
3393
3394void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
3395 WriteBarrierMode mode) {
3396 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003397 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kScopeInfoOffset, mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003398}
3399
3400
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003401Smi* SharedFunctionInfo::deopt_counter() {
3402 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3403}
3404
3405
3406void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3407 WRITE_FIELD(this, kDeoptCounterOffset, value);
3408}
3409
3410
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003411bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003412 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003413 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003414}
3415
3416
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003417bool SharedFunctionInfo::IsApiFunction() {
3418 return function_data()->IsFunctionTemplateInfo();
3419}
3420
3421
3422FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3423 ASSERT(IsApiFunction());
3424 return FunctionTemplateInfo::cast(function_data());
3425}
3426
3427
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003428bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003429 return function_data()->IsSmi();
3430}
3431
3432
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003433BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3434 ASSERT(HasBuiltinFunctionId());
3435 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003436}
3437
3438
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003439int SharedFunctionInfo::code_age() {
3440 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3441}
3442
3443
3444void SharedFunctionInfo::set_code_age(int code_age) {
3445 set_compiler_hints(compiler_hints() |
3446 ((code_age & kCodeAgeMask) << kCodeAgeShift));
3447}
3448
3449
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003450bool SharedFunctionInfo::has_deoptimization_support() {
3451 Code* code = this->code();
3452 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3453}
3454
3455
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003456bool JSFunction::IsBuiltin() {
3457 return context()->global()->IsJSBuiltinsObject();
3458}
3459
3460
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003461bool JSFunction::NeedsArgumentsAdaption() {
3462 return shared()->formal_parameter_count() !=
3463 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3464}
3465
3466
3467bool JSFunction::IsOptimized() {
3468 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3469}
3470
3471
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003472bool JSFunction::IsOptimizable() {
3473 return code()->kind() == Code::FUNCTION && code()->optimizable();
3474}
3475
3476
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003477bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003478 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003479}
3480
3481
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003482Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003483 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003484}
3485
3486
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003487Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003488 return reinterpret_cast<Code*>(
3489 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003490}
3491
3492
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003493void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00003494 // Skip the write barrier because code is never in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003495 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003496 Address entry = value->entry();
3497 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003498}
3499
3500
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003501void JSFunction::ReplaceCode(Code* code) {
3502 bool was_optimized = IsOptimized();
3503 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3504
3505 set_code(code);
3506
3507 // Add/remove the function from the list of optimized functions for this
3508 // context based on the state change.
3509 if (!was_optimized && is_optimized) {
3510 context()->global_context()->AddOptimizedFunction(this);
3511 }
3512 if (was_optimized && !is_optimized) {
3513 context()->global_context()->RemoveOptimizedFunction(this);
3514 }
3515}
3516
3517
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003518Context* JSFunction::context() {
3519 return Context::cast(READ_FIELD(this, kContextOffset));
3520}
3521
3522
3523Object* JSFunction::unchecked_context() {
3524 return READ_FIELD(this, kContextOffset);
3525}
3526
3527
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003528SharedFunctionInfo* JSFunction::unchecked_shared() {
3529 return reinterpret_cast<SharedFunctionInfo*>(
3530 READ_FIELD(this, kSharedFunctionInfoOffset));
3531}
3532
3533
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003534void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003535 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003536 WRITE_FIELD(this, kContextOffset, value);
3537 WRITE_BARRIER(this, kContextOffset);
3538}
3539
3540ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3541 kPrototypeOrInitialMapOffset)
3542
3543
3544Map* JSFunction::initial_map() {
3545 return Map::cast(prototype_or_initial_map());
3546}
3547
3548
3549void JSFunction::set_initial_map(Map* value) {
3550 set_prototype_or_initial_map(value);
3551}
3552
3553
3554bool JSFunction::has_initial_map() {
3555 return prototype_or_initial_map()->IsMap();
3556}
3557
3558
3559bool JSFunction::has_instance_prototype() {
3560 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3561}
3562
3563
3564bool JSFunction::has_prototype() {
3565 return map()->has_non_instance_prototype() || has_instance_prototype();
3566}
3567
3568
3569Object* JSFunction::instance_prototype() {
3570 ASSERT(has_instance_prototype());
3571 if (has_initial_map()) return initial_map()->prototype();
3572 // When there is no initial map and the prototype is a JSObject, the
3573 // initial map field is used for the prototype field.
3574 return prototype_or_initial_map();
3575}
3576
3577
3578Object* JSFunction::prototype() {
3579 ASSERT(has_prototype());
3580 // If the function's prototype property has been set to a non-JSObject
3581 // value, that value is stored in the constructor field of the map.
3582 if (map()->has_non_instance_prototype()) return map()->constructor();
3583 return instance_prototype();
3584}
3585
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003586bool JSFunction::should_have_prototype() {
3587 return map()->function_with_prototype();
3588}
3589
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003590
3591bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003592 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003593}
3594
3595
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003596int JSFunction::NumberOfLiterals() {
3597 return literals()->length();
3598}
3599
3600
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003601Object* JSBuiltinsObject::javascript_builtin(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 READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003604}
3605
3606
3607void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3608 Object* 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, OffsetOfFunctionWithId(id), value);
3611 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
3612}
3613
3614
3615Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003616 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003617 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3618}
3619
3620
3621void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3622 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003623 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003624 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003625 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003626}
3627
3628
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003629ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
3630
3631
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003632Address Foreign::address() {
3633 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003634}
3635
3636
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003637void Foreign::set_address(Address value) {
3638 WRITE_INTPTR_FIELD(this, kAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003639}
3640
3641
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003642ACCESSORS(JSValue, value, Object, kValueOffset)
3643
3644
3645JSValue* JSValue::cast(Object* obj) {
3646 ASSERT(obj->IsJSValue());
3647 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3648 return reinterpret_cast<JSValue*>(obj);
3649}
3650
3651
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003652ACCESSORS(JSMessageObject, type, String, kTypeOffset)
3653ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
3654ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
3655ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
3656ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
3657SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
3658SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
3659
3660
3661JSMessageObject* JSMessageObject::cast(Object* obj) {
3662 ASSERT(obj->IsJSMessageObject());
3663 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
3664 return reinterpret_cast<JSMessageObject*>(obj);
3665}
3666
3667
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003668INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003669ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003670ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003671ACCESSORS(Code, next_code_flushing_candidate,
3672 Object, kNextCodeFlushingCandidateOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003673
3674
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003675byte* Code::instruction_start() {
3676 return FIELD_ADDR(this, kHeaderSize);
3677}
3678
3679
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003680byte* Code::instruction_end() {
3681 return instruction_start() + instruction_size();
3682}
3683
3684
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003685int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003686 return RoundUp(instruction_size(), kObjectAlignment);
3687}
3688
3689
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003690FixedArray* Code::unchecked_deoptimization_data() {
3691 return reinterpret_cast<FixedArray*>(
3692 READ_FIELD(this, kDeoptimizationDataOffset));
3693}
3694
3695
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003696ByteArray* Code::unchecked_relocation_info() {
3697 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003698}
3699
3700
3701byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003702 return unchecked_relocation_info()->GetDataStartAddress();
3703}
3704
3705
3706int Code::relocation_size() {
3707 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003708}
3709
3710
3711byte* Code::entry() {
3712 return instruction_start();
3713}
3714
3715
3716bool Code::contains(byte* pc) {
3717 return (instruction_start() <= pc) &&
ricow@chromium.org65fae842010-08-25 15:26:24 +00003718 (pc <= instruction_start() + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003719}
3720
3721
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003722ACCESSORS(JSArray, length, Object, kLengthOffset)
3723
3724
ager@chromium.org236ad962008-09-25 09:45:57 +00003725ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00003726
3727
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003728JSRegExp::Type JSRegExp::TypeTag() {
3729 Object* data = this->data();
3730 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
3731 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
3732 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00003733}
3734
3735
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00003736int JSRegExp::CaptureCount() {
3737 switch (TypeTag()) {
3738 case ATOM:
3739 return 0;
3740 case IRREGEXP:
3741 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
3742 default:
3743 UNREACHABLE();
3744 return -1;
3745 }
3746}
3747
3748
ager@chromium.orga74f0da2008-12-03 16:05:52 +00003749JSRegExp::Flags JSRegExp::GetFlags() {
3750 ASSERT(this->data()->IsFixedArray());
3751 Object* data = this->data();
3752 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
3753 return Flags(smi->value());
3754}
3755
3756
3757String* JSRegExp::Pattern() {
3758 ASSERT(this->data()->IsFixedArray());
3759 Object* data = this->data();
3760 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
3761 return pattern;
3762}
3763
3764
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003765Object* JSRegExp::DataAt(int index) {
3766 ASSERT(TypeTag() != NOT_COMPILED);
3767 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00003768}
3769
3770
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003771void JSRegExp::SetDataAt(int index, Object* value) {
3772 ASSERT(TypeTag() != NOT_COMPILED);
3773 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
3774 FixedArray::cast(data())->set(index, value);
3775}
3776
3777
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003778JSObject::ElementsKind JSObject::GetElementsKind() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003779 if (map()->has_fast_elements()) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003780 ASSERT(elements()->map() == GetHeap()->fixed_array_map() ||
3781 elements()->map() == GetHeap()->fixed_cow_array_map());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003782 return FAST_ELEMENTS;
3783 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003784 HeapObject* array = elements();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003785 if (array->IsFixedArray()) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003786 // FAST_ELEMENTS or DICTIONARY_ELEMENTS are both stored in a
3787 // FixedArray, but FAST_ELEMENTS is already handled above.
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003788 ASSERT(array->IsDictionary());
3789 return DICTIONARY_ELEMENTS;
3790 }
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003791 ASSERT(!map()->has_fast_elements());
ager@chromium.org3811b432009-10-28 14:53:37 +00003792 if (array->IsExternalArray()) {
3793 switch (array->map()->instance_type()) {
3794 case EXTERNAL_BYTE_ARRAY_TYPE:
3795 return EXTERNAL_BYTE_ELEMENTS;
3796 case EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE:
3797 return EXTERNAL_UNSIGNED_BYTE_ELEMENTS;
3798 case EXTERNAL_SHORT_ARRAY_TYPE:
3799 return EXTERNAL_SHORT_ELEMENTS;
3800 case EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE:
3801 return EXTERNAL_UNSIGNED_SHORT_ELEMENTS;
3802 case EXTERNAL_INT_ARRAY_TYPE:
3803 return EXTERNAL_INT_ELEMENTS;
3804 case EXTERNAL_UNSIGNED_INT_ARRAY_TYPE:
3805 return EXTERNAL_UNSIGNED_INT_ELEMENTS;
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003806 case EXTERNAL_FLOAT_ARRAY_TYPE:
3807 return EXTERNAL_FLOAT_ELEMENTS;
3808 case EXTERNAL_DOUBLE_ARRAY_TYPE:
3809 return EXTERNAL_DOUBLE_ELEMENTS;
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003810 case EXTERNAL_PIXEL_ARRAY_TYPE:
3811 return EXTERNAL_PIXEL_ELEMENTS;
ager@chromium.org3811b432009-10-28 14:53:37 +00003812 default:
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003813 break;
ager@chromium.org3811b432009-10-28 14:53:37 +00003814 }
3815 }
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003816 UNREACHABLE();
3817 return DICTIONARY_ELEMENTS;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003818}
3819
3820
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003821bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003822 return GetElementsKind() == FAST_ELEMENTS;
3823}
3824
3825
3826bool JSObject::HasDictionaryElements() {
3827 return GetElementsKind() == DICTIONARY_ELEMENTS;
3828}
3829
3830
ager@chromium.org3811b432009-10-28 14:53:37 +00003831bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003832 HeapObject* array = elements();
3833 ASSERT(array != NULL);
3834 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00003835}
3836
3837
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003838#define EXTERNAL_ELEMENTS_CHECK(name, type) \
3839bool JSObject::HasExternal##name##Elements() { \
3840 HeapObject* array = elements(); \
3841 ASSERT(array != NULL); \
3842 if (!array->IsHeapObject()) \
3843 return false; \
3844 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00003845}
3846
3847
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003848EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
3849EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
3850EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
3851EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
3852 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
3853EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
3854EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
3855 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
3856EXTERNAL_ELEMENTS_CHECK(Float,
3857 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003858EXTERNAL_ELEMENTS_CHECK(Double,
3859 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003860EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00003861
3862
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003863bool JSObject::HasNamedInterceptor() {
3864 return map()->has_named_interceptor();
3865}
3866
3867
3868bool JSObject::HasIndexedInterceptor() {
3869 return map()->has_indexed_interceptor();
3870}
3871
3872
ager@chromium.org5c838252010-02-19 08:53:10 +00003873bool JSObject::AllowsSetElementsLength() {
3874 bool result = elements()->IsFixedArray();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003875 ASSERT(result == !HasExternalArrayElements());
ager@chromium.org5c838252010-02-19 08:53:10 +00003876 return result;
3877}
3878
3879
lrn@chromium.org303ada72010-10-27 09:33:13 +00003880MaybeObject* JSObject::EnsureWritableFastElements() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003881 ASSERT(HasFastElements());
3882 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003883 Isolate* isolate = GetIsolate();
3884 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003885 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003886 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
3887 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00003888 if (!maybe_writable_elems->ToObject(&writable_elems)) {
3889 return maybe_writable_elems;
3890 }
3891 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003892 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003893 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003894 return writable_elems;
3895}
3896
3897
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003898StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003899 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003900 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003901}
3902
3903
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003904NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003905 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003906 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003907}
3908
3909
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003910bool String::IsHashFieldComputed(uint32_t field) {
3911 return (field & kHashNotComputedMask) == 0;
3912}
3913
3914
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003915bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003916 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003917}
3918
3919
3920uint32_t String::Hash() {
3921 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003922 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003923 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003924 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003925 return ComputeAndSetHash();
3926}
3927
3928
ager@chromium.org7c537e22008-10-16 08:43:32 +00003929StringHasher::StringHasher(int length)
3930 : length_(length),
3931 raw_running_hash_(0),
3932 array_index_(0),
3933 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
3934 is_first_char_(true),
3935 is_valid_(true) { }
3936
3937
3938bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003939 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00003940}
3941
3942
3943void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003944 // Use the Jenkins one-at-a-time hash function to update the hash
3945 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003946 raw_running_hash_ += c;
3947 raw_running_hash_ += (raw_running_hash_ << 10);
3948 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003949 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003950 if (is_array_index_) {
3951 if (c < '0' || c > '9') {
3952 is_array_index_ = false;
3953 } else {
3954 int d = c - '0';
3955 if (is_first_char_) {
3956 is_first_char_ = false;
3957 if (c == '0' && length_ > 1) {
3958 is_array_index_ = false;
3959 return;
3960 }
3961 }
3962 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
3963 is_array_index_ = false;
3964 } else {
3965 array_index_ = array_index_ * 10 + d;
3966 }
3967 }
3968 }
3969}
3970
3971
3972void StringHasher::AddCharacterNoIndex(uc32 c) {
3973 ASSERT(!is_array_index());
3974 raw_running_hash_ += c;
3975 raw_running_hash_ += (raw_running_hash_ << 10);
3976 raw_running_hash_ ^= (raw_running_hash_ >> 6);
3977}
3978
3979
3980uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003981 // Get the calculated raw hash value and do some more bit ops to distribute
3982 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003983 uint32_t result = raw_running_hash_;
3984 result += (result << 3);
3985 result ^= (result >> 11);
3986 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003987 if (result == 0) {
3988 result = 27;
3989 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00003990 return result;
3991}
3992
3993
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003994template <typename schar>
3995uint32_t HashSequentialString(const schar* chars, int length) {
3996 StringHasher hasher(length);
3997 if (!hasher.has_trivial_hash()) {
3998 int i;
3999 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4000 hasher.AddCharacter(chars[i]);
4001 }
4002 for (; i < length; i++) {
4003 hasher.AddCharacterNoIndex(chars[i]);
4004 }
4005 }
4006 return hasher.GetHashField();
4007}
4008
4009
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004010bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004011 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004012 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4013 return false;
4014 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004015 return SlowAsArrayIndex(index);
4016}
4017
4018
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004019Object* JSReceiver::GetPrototype() {
4020 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004021}
4022
4023
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004024PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004025 return GetPropertyAttributeWithReceiver(this, key);
4026}
4027
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004028// TODO(504): this may be useful in other places too where JSGlobalProxy
4029// is used.
4030Object* JSObject::BypassGlobalProxy() {
4031 if (IsJSGlobalProxy()) {
4032 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004033 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004034 ASSERT(proto->IsJSGlobalObject());
4035 return proto;
4036 }
4037 return this;
4038}
4039
4040
4041bool JSObject::HasHiddenPropertiesObject() {
4042 ASSERT(!IsJSGlobalProxy());
4043 return GetPropertyAttributePostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004044 GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004045 false) != ABSENT;
4046}
4047
4048
4049Object* JSObject::GetHiddenPropertiesObject() {
4050 ASSERT(!IsJSGlobalProxy());
4051 PropertyAttributes attributes;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004052 // You can't install a getter on a property indexed by the hidden symbol,
4053 // so we can be sure that GetLocalPropertyPostInterceptor returns a real
4054 // object.
4055 Object* result =
4056 GetLocalPropertyPostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004057 GetHeap()->hidden_symbol(),
lrn@chromium.org303ada72010-10-27 09:33:13 +00004058 &attributes)->ToObjectUnchecked();
4059 return result;
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004060}
4061
4062
lrn@chromium.org303ada72010-10-27 09:33:13 +00004063MaybeObject* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004064 ASSERT(!IsJSGlobalProxy());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004065 return SetPropertyPostInterceptor(GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004066 hidden_obj,
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00004067 DONT_ENUM,
4068 kNonStrictMode);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004069}
4070
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004071
4072bool JSObject::HasElement(uint32_t index) {
4073 return HasElementWithReceiver(this, index);
4074}
4075
4076
4077bool AccessorInfo::all_can_read() {
4078 return BooleanBit::get(flag(), kAllCanReadBit);
4079}
4080
4081
4082void AccessorInfo::set_all_can_read(bool value) {
4083 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4084}
4085
4086
4087bool AccessorInfo::all_can_write() {
4088 return BooleanBit::get(flag(), kAllCanWriteBit);
4089}
4090
4091
4092void AccessorInfo::set_all_can_write(bool value) {
4093 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4094}
4095
4096
ager@chromium.org870a0b62008-11-04 11:43:05 +00004097bool AccessorInfo::prohibits_overwriting() {
4098 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4099}
4100
4101
4102void AccessorInfo::set_prohibits_overwriting(bool value) {
4103 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4104}
4105
4106
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004107PropertyAttributes AccessorInfo::property_attributes() {
4108 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4109}
4110
4111
4112void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
4113 ASSERT(AttributesField::is_valid(attributes));
4114 int rest_value = flag()->value() & ~AttributesField::mask();
4115 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
4116}
4117
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004118
4119template<typename Shape, typename Key>
4120void Dictionary<Shape, Key>::SetEntry(int entry,
4121 Object* key,
4122 Object* value) {
4123 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4124}
4125
4126
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004127template<typename Shape, typename Key>
4128void Dictionary<Shape, Key>::SetEntry(int entry,
4129 Object* key,
4130 Object* value,
4131 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004132 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004133 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004134 AssertNoAllocation no_gc;
4135 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004136 FixedArray::set(index, key, mode);
4137 FixedArray::set(index+1, value, mode);
4138 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004139}
4140
4141
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004142bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4143 ASSERT(other->IsNumber());
4144 return key == static_cast<uint32_t>(other->Number());
4145}
4146
4147
4148uint32_t NumberDictionaryShape::Hash(uint32_t key) {
4149 return ComputeIntegerHash(key);
4150}
4151
4152
4153uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
4154 ASSERT(other->IsNumber());
4155 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
4156}
4157
4158
4159MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4160 return Isolate::Current()->heap()->NumberFromUint32(key);
4161}
4162
4163
4164bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4165 // We know that all entries in a hash table had their hash keys created.
4166 // Use that knowledge to have fast failure.
4167 if (key->Hash() != String::cast(other)->Hash()) return false;
4168 return key->Equals(String::cast(other));
4169}
4170
4171
4172uint32_t StringDictionaryShape::Hash(String* key) {
4173 return key->Hash();
4174}
4175
4176
4177uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4178 return String::cast(other)->Hash();
4179}
4180
4181
4182MaybeObject* StringDictionaryShape::AsObject(String* key) {
4183 return key;
4184}
4185
4186
4187void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004188 // No write barrier is needed since empty_fixed_array is not in new space.
4189 // Please note this function is used during marking:
4190 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004191 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4192 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004193}
4194
4195
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004196void JSArray::EnsureSize(int required_size) {
4197 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004198 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004199 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4200 if (elts->length() < required_size) {
4201 // Doubling in size would be overkill, but leave some slack to avoid
4202 // constantly growing.
4203 Expand(required_size + (required_size >> 3));
4204 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004205 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004206 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4207 // Expand will allocate a new backing store in new space even if the size
4208 // we asked for isn't larger than what we had before.
4209 Expand(required_size);
4210 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004211}
4212
4213
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004214void JSArray::set_length(Smi* length) {
4215 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4216}
4217
4218
ager@chromium.org7c537e22008-10-16 08:43:32 +00004219void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004220 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004221 set_elements(storage);
4222}
4223
4224
lrn@chromium.org303ada72010-10-27 09:33:13 +00004225MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004226 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004227 return GetHeap()->CopyFixedArray(this);
4228}
4229
4230
4231Relocatable::Relocatable(Isolate* isolate) {
4232 ASSERT(isolate == Isolate::Current());
4233 isolate_ = isolate;
4234 prev_ = isolate->relocatable_top();
4235 isolate->set_relocatable_top(this);
4236}
4237
4238
4239Relocatable::~Relocatable() {
4240 ASSERT(isolate_ == Isolate::Current());
4241 ASSERT_EQ(isolate_->relocatable_top(), this);
4242 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004243}
4244
4245
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004246int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4247 return map->instance_size();
4248}
4249
4250
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004251void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004252 v->VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004253 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004254}
4255
4256
4257template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004258void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004259 StaticVisitor::VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004260 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004261}
4262
4263
4264void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4265 typedef v8::String::ExternalAsciiStringResource Resource;
4266 v->VisitExternalAsciiString(
4267 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4268}
4269
4270
4271template<typename StaticVisitor>
4272void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4273 typedef v8::String::ExternalAsciiStringResource Resource;
4274 StaticVisitor::VisitExternalAsciiString(
4275 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4276}
4277
4278
4279void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4280 typedef v8::String::ExternalStringResource Resource;
4281 v->VisitExternalTwoByteString(
4282 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4283}
4284
4285
4286template<typename StaticVisitor>
4287void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4288 typedef v8::String::ExternalStringResource Resource;
4289 StaticVisitor::VisitExternalTwoByteString(
4290 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4291}
4292
4293#define SLOT_ADDR(obj, offset) \
4294 reinterpret_cast<Object**>((obj)->address() + offset)
4295
4296template<int start_offset, int end_offset, int size>
4297void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4298 HeapObject* obj,
4299 ObjectVisitor* v) {
4300 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4301}
4302
4303
4304template<int start_offset>
4305void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4306 int object_size,
4307 ObjectVisitor* v) {
4308 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4309}
4310
4311#undef SLOT_ADDR
4312
4313
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004314#undef CAST_ACCESSOR
4315#undef INT_ACCESSORS
4316#undef SMI_ACCESSORS
4317#undef ACCESSORS
4318#undef FIELD_ADDR
4319#undef READ_FIELD
4320#undef WRITE_FIELD
4321#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004322#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004323#undef READ_MEMADDR_FIELD
4324#undef WRITE_MEMADDR_FIELD
4325#undef READ_DOUBLE_FIELD
4326#undef WRITE_DOUBLE_FIELD
4327#undef READ_INT_FIELD
4328#undef WRITE_INT_FIELD
4329#undef READ_SHORT_FIELD
4330#undef WRITE_SHORT_FIELD
4331#undef READ_BYTE_FIELD
4332#undef WRITE_BYTE_FIELD
4333
4334
4335} } // namespace v8::internal
4336
4337#endif // V8_OBJECTS_INL_H_