blob: 72dca225900ae5815fb92b106d86351aaa01b069 [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
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000691bool Object::IsPolymorphicCodeCacheHashTable() {
692 return IsHashTable();
693}
694
695
ager@chromium.org236ad962008-09-25 09:45:57 +0000696bool Object::IsMapCache() {
697 return IsHashTable();
698}
699
700
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000701bool Object::IsPrimitive() {
702 return IsOddball() || IsNumber() || IsString();
703}
704
705
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000706bool Object::IsJSGlobalProxy() {
707 bool result = IsHeapObject() &&
708 (HeapObject::cast(this)->map()->instance_type() ==
709 JS_GLOBAL_PROXY_TYPE);
710 ASSERT(!result || IsAccessCheckNeeded());
711 return result;
712}
713
714
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000715bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000716 if (!IsHeapObject()) return false;
717
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000718 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000719 return type == JS_GLOBAL_OBJECT_TYPE ||
720 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000721}
722
723
724bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000725 return IsHeapObject() &&
726 (HeapObject::cast(this)->map()->instance_type() ==
727 JS_GLOBAL_OBJECT_TYPE);
728}
729
730
731bool Object::IsJSBuiltinsObject() {
732 return IsHeapObject() &&
733 (HeapObject::cast(this)->map()->instance_type() ==
734 JS_BUILTINS_OBJECT_TYPE);
735}
736
737
738bool Object::IsUndetectableObject() {
739 return IsHeapObject()
740 && HeapObject::cast(this)->map()->is_undetectable();
741}
742
743
744bool Object::IsAccessCheckNeeded() {
745 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000746 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000747}
748
749
750bool Object::IsStruct() {
751 if (!IsHeapObject()) return false;
752 switch (HeapObject::cast(this)->map()->instance_type()) {
753#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
754 STRUCT_LIST(MAKE_STRUCT_CASE)
755#undef MAKE_STRUCT_CASE
756 default: return false;
757 }
758}
759
760
761#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
762 bool Object::Is##Name() { \
763 return Object::IsHeapObject() \
764 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
765 }
766 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
767#undef MAKE_STRUCT_PREDICATE
768
769
770bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000771 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000772}
773
774
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000775bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000776 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
777}
778
779
780bool Object::IsTheHole() {
781 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000782}
783
784
785bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000786 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000787}
788
789
790bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000791 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000792}
793
794
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000795bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000796 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000797}
798
799
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000800double Object::Number() {
801 ASSERT(IsNumber());
802 return IsSmi()
803 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
804 : reinterpret_cast<HeapNumber*>(this)->value();
805}
806
807
lrn@chromium.org303ada72010-10-27 09:33:13 +0000808MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000809 if (IsSmi()) return this;
810 if (IsHeapNumber()) {
811 double value = HeapNumber::cast(this)->value();
812 int int_value = FastD2I(value);
813 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
814 return Smi::FromInt(int_value);
815 }
816 }
817 return Failure::Exception();
818}
819
820
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000821bool Object::HasSpecificClassOf(String* name) {
822 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
823}
824
825
lrn@chromium.org303ada72010-10-27 09:33:13 +0000826MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000827 // GetElement can trigger a getter which can cause allocation.
828 // This was not always the case. This ASSERT is here to catch
829 // leftover incorrect uses.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000830 ASSERT(HEAP->IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000831 return GetElementWithReceiver(this, index);
832}
833
834
lrn@chromium.org303ada72010-10-27 09:33:13 +0000835Object* Object::GetElementNoExceptionThrown(uint32_t index) {
836 MaybeObject* maybe = GetElementWithReceiver(this, index);
837 ASSERT(!maybe->IsFailure());
838 Object* result = NULL; // Initialization to please compiler.
839 maybe->ToObject(&result);
840 return result;
841}
842
843
844MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000845 PropertyAttributes attributes;
846 return GetPropertyWithReceiver(this, key, &attributes);
847}
848
849
lrn@chromium.org303ada72010-10-27 09:33:13 +0000850MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000851 return GetPropertyWithReceiver(this, key, attributes);
852}
853
854
855#define FIELD_ADDR(p, offset) \
856 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
857
858#define READ_FIELD(p, offset) \
859 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
860
861#define WRITE_FIELD(p, offset, value) \
862 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
863
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000864// TODO(isolates): Pass heap in to these macros.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000865#define WRITE_BARRIER(object, offset) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000866 object->GetHeap()->RecordWrite(object->address(), offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000867
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000868// CONDITIONAL_WRITE_BARRIER must be issued after the actual
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000869// write due to the assert validating the written value.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000870#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, mode) \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000871 if (mode == UPDATE_WRITE_BARRIER) { \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000872 heap->RecordWrite(object->address(), offset); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000873 } else { \
874 ASSERT(mode == SKIP_WRITE_BARRIER); \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000875 ASSERT(heap->InNewSpace(object) || \
876 !heap->InNewSpace(READ_FIELD(object, offset)) || \
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000877 Page::FromAddress(object->address())-> \
878 IsRegionDirty(object->address() + offset)); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000879 }
880
lrn@chromium.org7516f052011-03-30 08:52:27 +0000881#ifndef V8_TARGET_ARCH_MIPS
882 #define READ_DOUBLE_FIELD(p, offset) \
883 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
884#else // V8_TARGET_ARCH_MIPS
885 // Prevent gcc from using load-double (mips ldc1) on (possibly)
886 // non-64-bit aligned HeapNumber::value.
887 static inline double read_double_field(HeapNumber* p, int offset) {
888 union conversion {
889 double d;
890 uint32_t u[2];
891 } c;
892 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
893 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
894 return c.d;
895 }
896 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
897#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000898
lrn@chromium.org7516f052011-03-30 08:52:27 +0000899
900#ifndef V8_TARGET_ARCH_MIPS
901 #define WRITE_DOUBLE_FIELD(p, offset, value) \
902 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
903#else // V8_TARGET_ARCH_MIPS
904 // Prevent gcc from using store-double (mips sdc1) on (possibly)
905 // non-64-bit aligned HeapNumber::value.
906 static inline void write_double_field(HeapNumber* p, int offset,
907 double value) {
908 union conversion {
909 double d;
910 uint32_t u[2];
911 } c;
912 c.d = value;
913 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
914 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
915 }
916 #define WRITE_DOUBLE_FIELD(p, offset, value) \
917 write_double_field(p, offset, value)
918#endif // V8_TARGET_ARCH_MIPS
919
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000920
921#define READ_INT_FIELD(p, offset) \
922 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
923
924#define WRITE_INT_FIELD(p, offset, value) \
925 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
926
ager@chromium.org3e875802009-06-29 08:26:34 +0000927#define READ_INTPTR_FIELD(p, offset) \
928 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
929
930#define WRITE_INTPTR_FIELD(p, offset, value) \
931 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
932
ager@chromium.org7c537e22008-10-16 08:43:32 +0000933#define READ_UINT32_FIELD(p, offset) \
934 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
935
936#define WRITE_UINT32_FIELD(p, offset, value) \
937 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
938
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000939#define READ_SHORT_FIELD(p, offset) \
940 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
941
942#define WRITE_SHORT_FIELD(p, offset, value) \
943 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
944
945#define READ_BYTE_FIELD(p, offset) \
946 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
947
948#define WRITE_BYTE_FIELD(p, offset, value) \
949 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
950
951
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000952Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
953 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000954}
955
956
957int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000958 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000959}
960
961
962Smi* Smi::FromInt(int value) {
963 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000964 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000965 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000966 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000967 return reinterpret_cast<Smi*>(tagged_value);
968}
969
970
971Smi* Smi::FromIntptr(intptr_t value) {
972 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000973 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
974 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000975}
976
977
978Failure::Type Failure::type() const {
979 return static_cast<Type>(value() & kFailureTypeTagMask);
980}
981
982
983bool Failure::IsInternalError() const {
984 return type() == INTERNAL_ERROR;
985}
986
987
988bool Failure::IsOutOfMemoryException() const {
989 return type() == OUT_OF_MEMORY_EXCEPTION;
990}
991
992
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000993AllocationSpace Failure::allocation_space() const {
994 ASSERT_EQ(RETRY_AFTER_GC, type());
995 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
996 & kSpaceTagMask);
997}
998
999
1000Failure* Failure::InternalError() {
1001 return Construct(INTERNAL_ERROR);
1002}
1003
1004
1005Failure* Failure::Exception() {
1006 return Construct(EXCEPTION);
1007}
1008
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00001009
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001010Failure* Failure::OutOfMemoryException() {
1011 return Construct(OUT_OF_MEMORY_EXCEPTION);
1012}
1013
1014
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001015intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001016 return static_cast<intptr_t>(
1017 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001018}
1019
1020
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001021Failure* Failure::RetryAfterGC() {
1022 return RetryAfterGC(NEW_SPACE);
1023}
1024
1025
1026Failure* Failure::RetryAfterGC(AllocationSpace space) {
1027 ASSERT((space & ~kSpaceTagMask) == 0);
1028 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001029}
1030
1031
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001032Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001033 uintptr_t info =
1034 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001035 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001036 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001037}
1038
1039
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001040bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001041#ifdef DEBUG
1042 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1043#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001044
1045#ifdef V8_TARGET_ARCH_X64
1046 // To be representable as a long smi, the value must be a 32-bit integer.
1047 bool result = (value == static_cast<int32_t>(value));
1048#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001049 // To be representable as an tagged small integer, the two
1050 // most-significant bits of 'value' must be either 00 or 11 due to
1051 // sign-extension. To check this we add 01 to the two
1052 // most-significant bits, and check if the most-significant bit is 0
1053 //
1054 // CAUTION: The original code below:
1055 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1056 // may lead to incorrect results according to the C language spec, and
1057 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1058 // compiler may produce undefined results in case of signed integer
1059 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001060 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001061#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001062 ASSERT(result == in_range);
1063 return result;
1064}
1065
1066
kasper.lund7276f142008-07-30 08:49:36 +00001067MapWord MapWord::FromMap(Map* map) {
1068 return MapWord(reinterpret_cast<uintptr_t>(map));
1069}
1070
1071
1072Map* MapWord::ToMap() {
1073 return reinterpret_cast<Map*>(value_);
1074}
1075
1076
1077bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001078 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001079}
1080
1081
1082MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001083 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1084 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001085}
1086
1087
1088HeapObject* MapWord::ToForwardingAddress() {
1089 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001090 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001091}
1092
1093
1094bool MapWord::IsMarked() {
1095 return (value_ & kMarkingMask) == 0;
1096}
1097
1098
1099void MapWord::SetMark() {
1100 value_ &= ~kMarkingMask;
1101}
1102
1103
1104void MapWord::ClearMark() {
1105 value_ |= kMarkingMask;
1106}
1107
1108
1109bool MapWord::IsOverflowed() {
1110 return (value_ & kOverflowMask) != 0;
1111}
1112
1113
1114void MapWord::SetOverflow() {
1115 value_ |= kOverflowMask;
1116}
1117
1118
1119void MapWord::ClearOverflow() {
1120 value_ &= ~kOverflowMask;
1121}
1122
1123
1124MapWord MapWord::EncodeAddress(Address map_address, int offset) {
1125 // Offset is the distance in live bytes from the first live object in the
1126 // same page. The offset between two objects in the same page should not
1127 // exceed the object area size of a page.
1128 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
1129
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001130 uintptr_t compact_offset = offset >> kObjectAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001131 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
1132
1133 Page* map_page = Page::FromAddress(map_address);
1134 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
1135
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001136 uintptr_t map_page_offset =
1137 map_page->Offset(map_address) >> kMapAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001138
1139 uintptr_t encoding =
1140 (compact_offset << kForwardingOffsetShift) |
1141 (map_page_offset << kMapPageOffsetShift) |
1142 (map_page->mc_page_index << kMapPageIndexShift);
1143 return MapWord(encoding);
1144}
1145
1146
1147Address MapWord::DecodeMapAddress(MapSpace* map_space) {
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001148 int map_page_index =
1149 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
kasper.lund7276f142008-07-30 08:49:36 +00001150 ASSERT_MAP_PAGE_INDEX(map_page_index);
1151
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001152 int map_page_offset = static_cast<int>(
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001153 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift) <<
1154 kMapAlignmentBits);
kasper.lund7276f142008-07-30 08:49:36 +00001155
1156 return (map_space->PageAddress(map_page_index) + map_page_offset);
1157}
1158
1159
1160int MapWord::DecodeOffset() {
1161 // The offset field is represented in the kForwardingOffsetBits
1162 // most-significant bits.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001163 uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
1164 ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize));
1165 return static_cast<int>(offset);
kasper.lund7276f142008-07-30 08:49:36 +00001166}
1167
1168
1169MapWord MapWord::FromEncodedAddress(Address address) {
1170 return MapWord(reinterpret_cast<uintptr_t>(address));
1171}
1172
1173
1174Address MapWord::ToEncodedAddress() {
1175 return reinterpret_cast<Address>(value_);
1176}
1177
1178
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001179#ifdef DEBUG
1180void HeapObject::VerifyObjectField(int offset) {
1181 VerifyPointer(READ_FIELD(this, offset));
1182}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001183
1184void HeapObject::VerifySmiField(int offset) {
1185 ASSERT(READ_FIELD(this, offset)->IsSmi());
1186}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001187#endif
1188
1189
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001190Heap* HeapObject::GetHeap() {
1191 // During GC, the map pointer in HeapObject is used in various ways that
1192 // prevent us from retrieving Heap from the map.
1193 // Assert that we are not in GC, implement GC code in a way that it doesn't
1194 // pull heap from the map.
1195 ASSERT(HEAP->is_safe_to_read_maps());
1196 return map()->heap();
1197}
1198
1199
1200Isolate* HeapObject::GetIsolate() {
1201 return GetHeap()->isolate();
1202}
1203
1204
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001205Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001206 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001207}
1208
1209
1210void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001211 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001212}
1213
1214
kasper.lund7276f142008-07-30 08:49:36 +00001215MapWord HeapObject::map_word() {
1216 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1217}
1218
1219
1220void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001221 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001222 // here.
1223 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1224}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001225
1226
1227HeapObject* HeapObject::FromAddress(Address address) {
1228 ASSERT_TAG_ALIGNED(address);
1229 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1230}
1231
1232
1233Address HeapObject::address() {
1234 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1235}
1236
1237
1238int HeapObject::Size() {
1239 return SizeFromMap(map());
1240}
1241
1242
1243void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1244 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1245 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1246}
1247
1248
1249void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1250 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1251}
1252
1253
kasper.lund7276f142008-07-30 08:49:36 +00001254bool HeapObject::IsMarked() {
1255 return map_word().IsMarked();
1256}
1257
1258
1259void HeapObject::SetMark() {
1260 ASSERT(!IsMarked());
1261 MapWord first_word = map_word();
1262 first_word.SetMark();
1263 set_map_word(first_word);
1264}
1265
1266
1267void HeapObject::ClearMark() {
1268 ASSERT(IsMarked());
1269 MapWord first_word = map_word();
1270 first_word.ClearMark();
1271 set_map_word(first_word);
1272}
1273
1274
1275bool HeapObject::IsOverflowed() {
1276 return map_word().IsOverflowed();
1277}
1278
1279
1280void HeapObject::SetOverflow() {
1281 MapWord first_word = map_word();
1282 first_word.SetOverflow();
1283 set_map_word(first_word);
1284}
1285
1286
1287void HeapObject::ClearOverflow() {
1288 ASSERT(IsOverflowed());
1289 MapWord first_word = map_word();
1290 first_word.ClearOverflow();
1291 set_map_word(first_word);
1292}
1293
1294
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001295double HeapNumber::value() {
1296 return READ_DOUBLE_FIELD(this, kValueOffset);
1297}
1298
1299
1300void HeapNumber::set_value(double value) {
1301 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1302}
1303
1304
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001305int HeapNumber::get_exponent() {
1306 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1307 kExponentShift) - kExponentBias;
1308}
1309
1310
1311int HeapNumber::get_sign() {
1312 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1313}
1314
1315
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001316ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001317
1318
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001319HeapObject* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001320 Object* array = READ_FIELD(this, kElementsOffset);
1321 // In the assert below Dictionary is covered under FixedArray.
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001322 ASSERT(array->IsFixedArray() || array->IsExternalArray());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001323 return reinterpret_cast<HeapObject*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001324}
1325
1326
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001327void JSObject::set_elements(HeapObject* value, WriteBarrierMode mode) {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001328 ASSERT(map()->has_fast_elements() ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001329 (value->map() == GetHeap()->fixed_array_map() ||
1330 value->map() == GetHeap()->fixed_cow_array_map()));
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001331 // In the assert below Dictionary is covered under FixedArray.
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001332 ASSERT(value->IsFixedArray() || value->IsExternalArray());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001333 WRITE_FIELD(this, kElementsOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001334 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001335}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001336
1337
1338void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001339 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1340 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001341}
1342
1343
1344void JSObject::initialize_elements() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001345 ASSERT(map()->has_fast_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001346 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1347 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001348}
1349
1350
lrn@chromium.org303ada72010-10-27 09:33:13 +00001351MaybeObject* JSObject::ResetElements() {
1352 Object* obj;
1353 { MaybeObject* maybe_obj = map()->GetFastElementsMap();
1354 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1355 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001356 set_map(Map::cast(obj));
1357 initialize_elements();
1358 return this;
1359}
1360
1361
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001362ACCESSORS(Oddball, to_string, String, kToStringOffset)
1363ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1364
1365
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001366byte Oddball::kind() {
1367 return READ_BYTE_FIELD(this, kKindOffset);
1368}
1369
1370
1371void Oddball::set_kind(byte value) {
1372 WRITE_BYTE_FIELD(this, kKindOffset, value);
1373}
1374
1375
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001376Object* JSGlobalPropertyCell::value() {
1377 return READ_FIELD(this, kValueOffset);
1378}
1379
1380
1381void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1382 // The write barrier is not used for global property cells.
1383 ASSERT(!val->IsJSGlobalPropertyCell());
1384 WRITE_FIELD(this, kValueOffset, val);
1385}
1386
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001387
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001388int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001389 InstanceType type = map()->instance_type();
1390 // Check for the most common kind of JavaScript object before
1391 // falling into the generic switch. This speeds up the internal
1392 // field operations considerably on average.
1393 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1394 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001395 case JS_GLOBAL_PROXY_TYPE:
1396 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001397 case JS_GLOBAL_OBJECT_TYPE:
1398 return JSGlobalObject::kSize;
1399 case JS_BUILTINS_OBJECT_TYPE:
1400 return JSBuiltinsObject::kSize;
1401 case JS_FUNCTION_TYPE:
1402 return JSFunction::kSize;
1403 case JS_VALUE_TYPE:
1404 return JSValue::kSize;
1405 case JS_ARRAY_TYPE:
1406 return JSValue::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001407 case JS_REGEXP_TYPE:
1408 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001409 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001410 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001411 case JS_MESSAGE_OBJECT_TYPE:
1412 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001413 default:
1414 UNREACHABLE();
1415 return 0;
1416 }
1417}
1418
1419
1420int JSObject::GetInternalFieldCount() {
1421 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001422 // Make sure to adjust for the number of in-object properties. These
1423 // properties do contribute to the size, but are not internal fields.
1424 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1425 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001426}
1427
1428
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001429int JSObject::GetInternalFieldOffset(int index) {
1430 ASSERT(index < GetInternalFieldCount() && index >= 0);
1431 return GetHeaderSize() + (kPointerSize * index);
1432}
1433
1434
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001435Object* JSObject::GetInternalField(int index) {
1436 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001437 // Internal objects do follow immediately after the header, whereas in-object
1438 // properties are at the end of the object. Therefore there is no need
1439 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001440 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1441}
1442
1443
1444void JSObject::SetInternalField(int index, Object* value) {
1445 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001446 // Internal objects do follow immediately after the header, whereas in-object
1447 // properties are at the end of the object. Therefore there is no need
1448 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001449 int offset = GetHeaderSize() + (kPointerSize * index);
1450 WRITE_FIELD(this, offset, value);
1451 WRITE_BARRIER(this, offset);
1452}
1453
1454
ager@chromium.org7c537e22008-10-16 08:43:32 +00001455// Access fast-case object properties at index. The use of these routines
1456// is needed to correctly distinguish between properties stored in-object and
1457// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001458Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001459 // Adjust for the number of properties stored in the object.
1460 index -= map()->inobject_properties();
1461 if (index < 0) {
1462 int offset = map()->instance_size() + (index * kPointerSize);
1463 return READ_FIELD(this, offset);
1464 } else {
1465 ASSERT(index < properties()->length());
1466 return properties()->get(index);
1467 }
1468}
1469
1470
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001471Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001472 // Adjust for the number of properties stored in the object.
1473 index -= map()->inobject_properties();
1474 if (index < 0) {
1475 int offset = map()->instance_size() + (index * kPointerSize);
1476 WRITE_FIELD(this, offset, value);
1477 WRITE_BARRIER(this, offset);
1478 } else {
1479 ASSERT(index < properties()->length());
1480 properties()->set(index, value);
1481 }
1482 return value;
1483}
1484
1485
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001486int JSObject::GetInObjectPropertyOffset(int index) {
1487 // Adjust for the number of properties stored in the object.
1488 index -= map()->inobject_properties();
1489 ASSERT(index < 0);
1490 return map()->instance_size() + (index * kPointerSize);
1491}
1492
1493
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001494Object* JSObject::InObjectPropertyAt(int index) {
1495 // Adjust for the number of properties stored in the object.
1496 index -= map()->inobject_properties();
1497 ASSERT(index < 0);
1498 int offset = map()->instance_size() + (index * kPointerSize);
1499 return READ_FIELD(this, offset);
1500}
1501
1502
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001503Object* JSObject::InObjectPropertyAtPut(int index,
1504 Object* value,
1505 WriteBarrierMode mode) {
1506 // Adjust for the number of properties stored in the object.
1507 index -= map()->inobject_properties();
1508 ASSERT(index < 0);
1509 int offset = map()->instance_size() + (index * kPointerSize);
1510 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001511 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001512 return value;
1513}
1514
1515
1516
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001517void JSObject::InitializeBody(int object_size, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001518 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001519 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001520 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001521 }
1522}
1523
1524
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001525bool JSObject::HasFastProperties() {
1526 return !properties()->IsDictionary();
1527}
1528
1529
1530int JSObject::MaxFastProperties() {
1531 // Allow extra fast properties if the object has more than
1532 // kMaxFastProperties in-object properties. When this is the case,
1533 // it is very unlikely that the object is being used as a dictionary
1534 // and there is a good chance that allowing more map transitions
1535 // will be worth it.
1536 return Max(map()->inobject_properties(), kMaxFastProperties);
1537}
1538
1539
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001540void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001541 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001542 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001543 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001544 }
1545}
1546
1547
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001548bool Object::ToArrayIndex(uint32_t* index) {
1549 if (IsSmi()) {
1550 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001551 if (value < 0) return false;
1552 *index = value;
1553 return true;
1554 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001555 if (IsHeapNumber()) {
1556 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001557 uint32_t uint_value = static_cast<uint32_t>(value);
1558 if (value == static_cast<double>(uint_value)) {
1559 *index = uint_value;
1560 return true;
1561 }
1562 }
1563 return false;
1564}
1565
1566
1567bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1568 if (!this->IsJSValue()) return false;
1569
1570 JSValue* js_value = JSValue::cast(this);
1571 if (!js_value->value()->IsString()) return false;
1572
1573 String* str = String::cast(js_value->value());
1574 if (index >= (uint32_t)str->length()) return false;
1575
1576 return true;
1577}
1578
1579
1580Object* FixedArray::get(int index) {
1581 ASSERT(index >= 0 && index < this->length());
1582 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1583}
1584
1585
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001586void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001587 ASSERT(map() != HEAP->fixed_cow_array_map());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001588 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1589 int offset = kHeaderSize + index * kPointerSize;
1590 WRITE_FIELD(this, offset, value);
1591}
1592
1593
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001594void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001595 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001596 ASSERT(index >= 0 && index < this->length());
1597 int offset = kHeaderSize + index * kPointerSize;
1598 WRITE_FIELD(this, offset, value);
1599 WRITE_BARRIER(this, offset);
1600}
1601
1602
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001603WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001604 if (GetHeap()->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001605 return UPDATE_WRITE_BARRIER;
1606}
1607
1608
1609void FixedArray::set(int index,
1610 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001611 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001612 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001613 ASSERT(index >= 0 && index < this->length());
1614 int offset = kHeaderSize + index * kPointerSize;
1615 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001616 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001617}
1618
1619
1620void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001621 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001622 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001623 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001624 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1625}
1626
1627
1628void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001629 ASSERT(map() != HEAP->fixed_cow_array_map());
1630 set_undefined(GetHeap(), index);
1631}
1632
1633
1634void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001635 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001636 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001637 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001638 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001639}
1640
1641
ager@chromium.org236ad962008-09-25 09:45:57 +00001642void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001643 set_null(GetHeap(), index);
1644}
1645
1646
1647void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001648 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001649 ASSERT(!heap->InNewSpace(heap->null_value()));
1650 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001651}
1652
1653
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001654void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001655 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001656 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001657 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1658 WRITE_FIELD(this,
1659 kHeaderSize + index * kPointerSize,
1660 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001661}
1662
1663
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001664void FixedArray::set_unchecked(int index, Smi* value) {
1665 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1666 int offset = kHeaderSize + index * kPointerSize;
1667 WRITE_FIELD(this, offset, value);
1668}
1669
1670
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001671void FixedArray::set_unchecked(Heap* heap,
1672 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001673 Object* value,
1674 WriteBarrierMode mode) {
1675 int offset = kHeaderSize + index * kPointerSize;
1676 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001677 CONDITIONAL_WRITE_BARRIER(heap, this, offset, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001678}
1679
1680
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001681void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001682 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001683 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1684 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001685}
1686
1687
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001688Object** FixedArray::data_start() {
1689 return HeapObject::RawField(this, kHeaderSize);
1690}
1691
1692
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001693bool DescriptorArray::IsEmpty() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00001694 ASSERT(this->IsSmi() ||
1695 this->length() > kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001696 this == HEAP->empty_descriptor_array());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001697 return this->IsSmi() || length() <= kFirstIndex;
1698}
1699
1700
1701int DescriptorArray::bit_field3_storage() {
1702 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1703 return Smi::cast(storage)->value();
1704}
1705
1706void DescriptorArray::set_bit_field3_storage(int value) {
1707 ASSERT(!IsEmpty());
1708 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001709}
1710
1711
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001712void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1713 Object* tmp = array->get(first);
1714 fast_set(array, first, array->get(second));
1715 fast_set(array, second, tmp);
1716}
1717
1718
1719int DescriptorArray::Search(String* name) {
1720 SLOW_ASSERT(IsSortedNoDuplicates());
1721
1722 // Check for empty descriptor array.
1723 int nof = number_of_descriptors();
1724 if (nof == 0) return kNotFound;
1725
1726 // Fast case: do linear search for small arrays.
1727 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001728 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001729 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001730 }
1731
1732 // Slow case: perform binary search.
1733 return BinarySearch(name, 0, nof - 1);
1734}
1735
1736
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001737int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001738 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001739 if (number == DescriptorLookupCache::kAbsent) {
1740 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001741 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001742 }
1743 return number;
1744}
1745
1746
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001747String* DescriptorArray::GetKey(int descriptor_number) {
1748 ASSERT(descriptor_number < number_of_descriptors());
1749 return String::cast(get(ToKeyIndex(descriptor_number)));
1750}
1751
1752
1753Object* DescriptorArray::GetValue(int descriptor_number) {
1754 ASSERT(descriptor_number < number_of_descriptors());
1755 return GetContentArray()->get(ToValueIndex(descriptor_number));
1756}
1757
1758
1759Smi* DescriptorArray::GetDetails(int descriptor_number) {
1760 ASSERT(descriptor_number < number_of_descriptors());
1761 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1762}
1763
1764
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001765PropertyType DescriptorArray::GetType(int descriptor_number) {
1766 ASSERT(descriptor_number < number_of_descriptors());
1767 return PropertyDetails(GetDetails(descriptor_number)).type();
1768}
1769
1770
1771int DescriptorArray::GetFieldIndex(int descriptor_number) {
1772 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1773}
1774
1775
1776JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1777 return JSFunction::cast(GetValue(descriptor_number));
1778}
1779
1780
1781Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1782 ASSERT(GetType(descriptor_number) == CALLBACKS);
1783 return GetValue(descriptor_number);
1784}
1785
1786
1787AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1788 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001789 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
1790 return reinterpret_cast<AccessorDescriptor*>(p->address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001791}
1792
1793
1794bool DescriptorArray::IsProperty(int descriptor_number) {
1795 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1796}
1797
1798
1799bool DescriptorArray::IsTransition(int descriptor_number) {
1800 PropertyType t = GetType(descriptor_number);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001801 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION ||
1802 t == EXTERNAL_ARRAY_TRANSITION;
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001803}
1804
1805
1806bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1807 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1808}
1809
1810
1811bool DescriptorArray::IsDontEnum(int descriptor_number) {
1812 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1813}
1814
1815
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001816void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1817 desc->Init(GetKey(descriptor_number),
1818 GetValue(descriptor_number),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001819 PropertyDetails(GetDetails(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001820}
1821
1822
1823void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1824 // Range check.
1825 ASSERT(descriptor_number < number_of_descriptors());
1826
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001827 // Make sure none of the elements in desc are in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001828 ASSERT(!HEAP->InNewSpace(desc->GetKey()));
1829 ASSERT(!HEAP->InNewSpace(desc->GetValue()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001830
1831 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1832 FixedArray* content_array = GetContentArray();
1833 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1834 fast_set(content_array, ToDetailsIndex(descriptor_number),
1835 desc->GetDetails().AsSmi());
1836}
1837
1838
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001839void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1840 Descriptor desc;
1841 src->Get(src_index, &desc);
1842 Set(index, &desc);
1843}
1844
1845
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001846void DescriptorArray::Swap(int first, int second) {
1847 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1848 FixedArray* content_array = GetContentArray();
1849 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1850 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1851}
1852
1853
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001854template<typename Shape, typename Key>
1855int HashTable<Shape, Key>::FindEntry(Key key) {
1856 return FindEntry(GetIsolate(), key);
1857}
1858
1859
1860// Find entry for key otherwise return kNotFound.
1861template<typename Shape, typename Key>
1862int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
1863 uint32_t capacity = Capacity();
1864 uint32_t entry = FirstProbe(Shape::Hash(key), capacity);
1865 uint32_t count = 1;
1866 // EnsureCapacity will guarantee the hash table is never full.
1867 while (true) {
1868 Object* element = KeyAt(entry);
1869 if (element == isolate->heap()->undefined_value()) break; // Empty entry.
1870 if (element != isolate->heap()->null_value() &&
1871 Shape::IsMatch(key, element)) return entry;
1872 entry = NextProbe(entry, count++, capacity);
1873 }
1874 return kNotFound;
1875}
1876
1877
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001878bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001879 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001880 if (!max_index_object->IsSmi()) return false;
1881 return 0 !=
1882 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1883}
1884
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001885uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001886 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001887 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001888 if (!max_index_object->IsSmi()) return 0;
1889 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1890 return value >> kRequiresSlowElementsTagSize;
1891}
1892
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001893void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001894 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001895}
1896
1897
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001898// ------------------------------------
1899// Cast operations
1900
1901
1902CAST_ACCESSOR(FixedArray)
1903CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00001904CAST_ACCESSOR(DeoptimizationInputData)
1905CAST_ACCESSOR(DeoptimizationOutputData)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001906CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00001907CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00001908CAST_ACCESSOR(NormalizedMapCache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00001909CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001910CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00001911CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00001912CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001913CAST_ACCESSOR(String)
1914CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00001915CAST_ACCESSOR(SeqAsciiString)
1916CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001917CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001918CAST_ACCESSOR(ExternalString)
1919CAST_ACCESSOR(ExternalAsciiString)
1920CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001921CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001922CAST_ACCESSOR(JSObject)
1923CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001924CAST_ACCESSOR(HeapObject)
1925CAST_ACCESSOR(HeapNumber)
1926CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001927CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001928CAST_ACCESSOR(SharedFunctionInfo)
1929CAST_ACCESSOR(Map)
1930CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001931CAST_ACCESSOR(GlobalObject)
1932CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001933CAST_ACCESSOR(JSGlobalObject)
1934CAST_ACCESSOR(JSBuiltinsObject)
1935CAST_ACCESSOR(Code)
1936CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00001937CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00001938CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00001939CAST_ACCESSOR(JSFunctionProxy)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001940CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001941CAST_ACCESSOR(ByteArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00001942CAST_ACCESSOR(ExternalArray)
1943CAST_ACCESSOR(ExternalByteArray)
1944CAST_ACCESSOR(ExternalUnsignedByteArray)
1945CAST_ACCESSOR(ExternalShortArray)
1946CAST_ACCESSOR(ExternalUnsignedShortArray)
1947CAST_ACCESSOR(ExternalIntArray)
1948CAST_ACCESSOR(ExternalUnsignedIntArray)
1949CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00001950CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00001951CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001952CAST_ACCESSOR(Struct)
1953
1954
1955#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
1956 STRUCT_LIST(MAKE_STRUCT_CAST)
1957#undef MAKE_STRUCT_CAST
1958
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001959
1960template <typename Shape, typename Key>
1961HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001962 ASSERT(obj->IsHashTable());
1963 return reinterpret_cast<HashTable*>(obj);
1964}
1965
1966
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001967SMI_ACCESSORS(FixedArray, length, kLengthOffset)
1968SMI_ACCESSORS(ByteArray, length, kLengthOffset)
1969
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001970INT_ACCESSORS(ExternalArray, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001971
1972
ager@chromium.orgac091b72010-05-05 07:34:42 +00001973SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001974
1975
1976uint32_t String::hash_field() {
1977 return READ_UINT32_FIELD(this, kHashFieldOffset);
1978}
1979
1980
1981void String::set_hash_field(uint32_t value) {
1982 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001983#if V8_HOST_ARCH_64_BIT
1984 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
1985#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00001986}
1987
1988
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001989bool String::Equals(String* other) {
1990 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001991 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
1992 return false;
1993 }
1994 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001995}
1996
1997
lrn@chromium.org303ada72010-10-27 09:33:13 +00001998MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00001999 if (!StringShape(this).IsCons()) return this;
2000 ConsString* cons = ConsString::cast(this);
2001 if (cons->second()->length() == 0) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002002 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002003}
2004
2005
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002006String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002007 MaybeObject* flat = TryFlatten(pretenure);
2008 Object* successfully_flattened;
2009 if (flat->ToObject(&successfully_flattened)) {
2010 return String::cast(successfully_flattened);
2011 }
2012 return this;
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002013}
2014
2015
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002016uint16_t String::Get(int index) {
2017 ASSERT(index >= 0 && index < length());
2018 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002019 case kSeqStringTag | kAsciiStringTag:
2020 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2021 case kSeqStringTag | kTwoByteStringTag:
2022 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2023 case kConsStringTag | kAsciiStringTag:
2024 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002025 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002026 case kExternalStringTag | kAsciiStringTag:
2027 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2028 case kExternalStringTag | kTwoByteStringTag:
2029 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002030 default:
2031 break;
2032 }
2033
2034 UNREACHABLE();
2035 return 0;
2036}
2037
2038
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002039void String::Set(int index, uint16_t value) {
2040 ASSERT(index >= 0 && index < length());
2041 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002042
ager@chromium.org5ec48922009-05-05 07:25:34 +00002043 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002044 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2045 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002046}
2047
2048
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002049bool String::IsFlat() {
2050 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002051 case kConsStringTag: {
2052 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00002053 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00002054 return second->length() == 0;
2055 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00002056 default:
2057 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002058 }
2059}
2060
2061
ager@chromium.org7c537e22008-10-16 08:43:32 +00002062uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002063 ASSERT(index >= 0 && index < length());
2064 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2065}
2066
2067
ager@chromium.org7c537e22008-10-16 08:43:32 +00002068void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002069 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2070 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2071 static_cast<byte>(value));
2072}
2073
2074
ager@chromium.org7c537e22008-10-16 08:43:32 +00002075Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002076 return FIELD_ADDR(this, kHeaderSize);
2077}
2078
2079
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002080char* SeqAsciiString::GetChars() {
2081 return reinterpret_cast<char*>(GetCharsAddress());
2082}
2083
2084
ager@chromium.org7c537e22008-10-16 08:43:32 +00002085Address SeqTwoByteString::GetCharsAddress() {
2086 return FIELD_ADDR(this, kHeaderSize);
2087}
2088
2089
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002090uc16* SeqTwoByteString::GetChars() {
2091 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2092}
2093
2094
ager@chromium.org7c537e22008-10-16 08:43:32 +00002095uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002096 ASSERT(index >= 0 && index < length());
2097 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2098}
2099
2100
ager@chromium.org7c537e22008-10-16 08:43:32 +00002101void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002102 ASSERT(index >= 0 && index < length());
2103 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2104}
2105
2106
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002107int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002108 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002109}
2110
2111
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002112int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002113 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002114}
2115
2116
ager@chromium.org870a0b62008-11-04 11:43:05 +00002117String* ConsString::first() {
2118 return String::cast(READ_FIELD(this, kFirstOffset));
2119}
2120
2121
2122Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002123 return READ_FIELD(this, kFirstOffset);
2124}
2125
2126
ager@chromium.org870a0b62008-11-04 11:43:05 +00002127void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002128 WRITE_FIELD(this, kFirstOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002129 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002130}
2131
2132
ager@chromium.org870a0b62008-11-04 11:43:05 +00002133String* ConsString::second() {
2134 return String::cast(READ_FIELD(this, kSecondOffset));
2135}
2136
2137
2138Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002139 return READ_FIELD(this, kSecondOffset);
2140}
2141
2142
ager@chromium.org870a0b62008-11-04 11:43:05 +00002143void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002144 WRITE_FIELD(this, kSecondOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002145 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002146}
2147
2148
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002149ExternalAsciiString::Resource* ExternalAsciiString::resource() {
2150 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2151}
2152
2153
2154void ExternalAsciiString::set_resource(
2155 ExternalAsciiString::Resource* resource) {
2156 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2157}
2158
2159
2160ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
2161 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2162}
2163
2164
2165void ExternalTwoByteString::set_resource(
2166 ExternalTwoByteString::Resource* resource) {
2167 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2168}
2169
2170
ager@chromium.orgac091b72010-05-05 07:34:42 +00002171void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002172 set_finger_index(kEntriesIndex);
2173 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002174}
2175
2176
2177void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002178 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002179 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002180 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002181 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002182 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002183 MakeZeroSize();
2184}
2185
2186
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002187int JSFunctionResultCache::size() {
2188 return Smi::cast(get(kCacheSizeIndex))->value();
2189}
2190
2191
2192void JSFunctionResultCache::set_size(int size) {
2193 set(kCacheSizeIndex, Smi::FromInt(size));
2194}
2195
2196
2197int JSFunctionResultCache::finger_index() {
2198 return Smi::cast(get(kFingerIndex))->value();
2199}
2200
2201
2202void JSFunctionResultCache::set_finger_index(int finger_index) {
2203 set(kFingerIndex, Smi::FromInt(finger_index));
2204}
2205
2206
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002207byte ByteArray::get(int index) {
2208 ASSERT(index >= 0 && index < this->length());
2209 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2210}
2211
2212
2213void ByteArray::set(int index, byte value) {
2214 ASSERT(index >= 0 && index < this->length());
2215 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2216}
2217
2218
2219int ByteArray::get_int(int index) {
2220 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2221 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2222}
2223
2224
2225ByteArray* ByteArray::FromDataStartAddress(Address address) {
2226 ASSERT_TAG_ALIGNED(address);
2227 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2228}
2229
2230
2231Address ByteArray::GetDataStartAddress() {
2232 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2233}
2234
2235
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002236uint8_t* ExternalPixelArray::external_pixel_pointer() {
2237 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002238}
2239
2240
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002241uint8_t ExternalPixelArray::get(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002242 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002243 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002244 return ptr[index];
2245}
2246
2247
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002248void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002249 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002250 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002251 ptr[index] = value;
2252}
2253
2254
ager@chromium.org3811b432009-10-28 14:53:37 +00002255void* ExternalArray::external_pointer() {
2256 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2257 return reinterpret_cast<void*>(ptr);
2258}
2259
2260
2261void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2262 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2263 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2264}
2265
2266
2267int8_t ExternalByteArray::get(int index) {
2268 ASSERT((index >= 0) && (index < this->length()));
2269 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2270 return ptr[index];
2271}
2272
2273
2274void ExternalByteArray::set(int index, int8_t value) {
2275 ASSERT((index >= 0) && (index < this->length()));
2276 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2277 ptr[index] = value;
2278}
2279
2280
2281uint8_t ExternalUnsignedByteArray::get(int index) {
2282 ASSERT((index >= 0) && (index < this->length()));
2283 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2284 return ptr[index];
2285}
2286
2287
2288void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2289 ASSERT((index >= 0) && (index < this->length()));
2290 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2291 ptr[index] = value;
2292}
2293
2294
2295int16_t ExternalShortArray::get(int index) {
2296 ASSERT((index >= 0) && (index < this->length()));
2297 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2298 return ptr[index];
2299}
2300
2301
2302void ExternalShortArray::set(int index, int16_t value) {
2303 ASSERT((index >= 0) && (index < this->length()));
2304 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2305 ptr[index] = value;
2306}
2307
2308
2309uint16_t ExternalUnsignedShortArray::get(int index) {
2310 ASSERT((index >= 0) && (index < this->length()));
2311 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2312 return ptr[index];
2313}
2314
2315
2316void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2317 ASSERT((index >= 0) && (index < this->length()));
2318 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2319 ptr[index] = value;
2320}
2321
2322
2323int32_t ExternalIntArray::get(int index) {
2324 ASSERT((index >= 0) && (index < this->length()));
2325 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2326 return ptr[index];
2327}
2328
2329
2330void ExternalIntArray::set(int index, int32_t value) {
2331 ASSERT((index >= 0) && (index < this->length()));
2332 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2333 ptr[index] = value;
2334}
2335
2336
2337uint32_t ExternalUnsignedIntArray::get(int index) {
2338 ASSERT((index >= 0) && (index < this->length()));
2339 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2340 return ptr[index];
2341}
2342
2343
2344void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2345 ASSERT((index >= 0) && (index < this->length()));
2346 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2347 ptr[index] = value;
2348}
2349
2350
2351float ExternalFloatArray::get(int index) {
2352 ASSERT((index >= 0) && (index < this->length()));
2353 float* ptr = static_cast<float*>(external_pointer());
2354 return ptr[index];
2355}
2356
2357
2358void ExternalFloatArray::set(int index, float value) {
2359 ASSERT((index >= 0) && (index < this->length()));
2360 float* ptr = static_cast<float*>(external_pointer());
2361 ptr[index] = value;
2362}
2363
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002364
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002365double ExternalDoubleArray::get(int index) {
2366 ASSERT((index >= 0) && (index < this->length()));
2367 double* ptr = static_cast<double*>(external_pointer());
2368 return ptr[index];
2369}
2370
2371
2372void ExternalDoubleArray::set(int index, double value) {
2373 ASSERT((index >= 0) && (index < this->length()));
2374 double* ptr = static_cast<double*>(external_pointer());
2375 ptr[index] = value;
2376}
2377
2378
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002379int Map::visitor_id() {
2380 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2381}
2382
2383
2384void Map::set_visitor_id(int id) {
2385 ASSERT(0 <= id && id < 256);
2386 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2387}
2388
ager@chromium.org3811b432009-10-28 14:53:37 +00002389
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002390int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002391 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2392}
2393
2394
2395int Map::inobject_properties() {
2396 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002397}
2398
2399
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002400int Map::pre_allocated_property_fields() {
2401 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2402}
2403
2404
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002405int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002406 int instance_size = map->instance_size();
2407 if (instance_size != kVariableSizeSentinel) return instance_size;
2408 // We can ignore the "symbol" bit becase it is only set for symbols
2409 // and implies a string type.
2410 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002411 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002412 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002413 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002414 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002415 if (instance_type == ASCII_STRING_TYPE) {
2416 return SeqAsciiString::SizeFor(
2417 reinterpret_cast<SeqAsciiString*>(this)->length());
2418 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002419 if (instance_type == BYTE_ARRAY_TYPE) {
2420 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2421 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002422 if (instance_type == STRING_TYPE) {
2423 return SeqTwoByteString::SizeFor(
2424 reinterpret_cast<SeqTwoByteString*>(this)->length());
2425 }
2426 ASSERT(instance_type == CODE_TYPE);
2427 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002428}
2429
2430
2431void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002432 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002433 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002434 ASSERT(0 <= value && value < 256);
2435 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2436}
2437
2438
ager@chromium.org7c537e22008-10-16 08:43:32 +00002439void Map::set_inobject_properties(int value) {
2440 ASSERT(0 <= value && value < 256);
2441 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2442}
2443
2444
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002445void Map::set_pre_allocated_property_fields(int value) {
2446 ASSERT(0 <= value && value < 256);
2447 WRITE_BYTE_FIELD(this,
2448 kPreAllocatedPropertyFieldsOffset,
2449 static_cast<byte>(value));
2450}
2451
2452
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002453InstanceType Map::instance_type() {
2454 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2455}
2456
2457
2458void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002459 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2460}
2461
2462
2463int Map::unused_property_fields() {
2464 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2465}
2466
2467
2468void Map::set_unused_property_fields(int value) {
2469 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2470}
2471
2472
2473byte Map::bit_field() {
2474 return READ_BYTE_FIELD(this, kBitFieldOffset);
2475}
2476
2477
2478void Map::set_bit_field(byte value) {
2479 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2480}
2481
2482
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002483byte Map::bit_field2() {
2484 return READ_BYTE_FIELD(this, kBitField2Offset);
2485}
2486
2487
2488void Map::set_bit_field2(byte value) {
2489 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2490}
2491
2492
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002493void Map::set_non_instance_prototype(bool value) {
2494 if (value) {
2495 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2496 } else {
2497 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2498 }
2499}
2500
2501
2502bool Map::has_non_instance_prototype() {
2503 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2504}
2505
2506
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002507void Map::set_function_with_prototype(bool value) {
2508 if (value) {
2509 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2510 } else {
2511 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2512 }
2513}
2514
2515
2516bool Map::function_with_prototype() {
2517 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2518}
2519
2520
ager@chromium.org870a0b62008-11-04 11:43:05 +00002521void Map::set_is_access_check_needed(bool access_check_needed) {
2522 if (access_check_needed) {
2523 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2524 } else {
2525 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2526 }
2527}
2528
2529
2530bool Map::is_access_check_needed() {
2531 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2532}
2533
2534
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002535void Map::set_is_extensible(bool value) {
2536 if (value) {
2537 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2538 } else {
2539 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2540 }
2541}
2542
2543bool Map::is_extensible() {
2544 return ((1 << kIsExtensible) & bit_field2()) != 0;
2545}
2546
2547
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002548void Map::set_attached_to_shared_function_info(bool value) {
2549 if (value) {
2550 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2551 } else {
2552 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2553 }
2554}
2555
2556bool Map::attached_to_shared_function_info() {
2557 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2558}
2559
2560
2561void Map::set_is_shared(bool value) {
2562 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002563 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002564 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002565 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002566 }
2567}
2568
2569bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002570 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002571}
2572
2573
2574JSFunction* Map::unchecked_constructor() {
2575 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2576}
2577
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002578
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002579FixedArray* Map::unchecked_prototype_transitions() {
2580 return reinterpret_cast<FixedArray*>(
2581 READ_FIELD(this, kPrototypeTransitionsOffset));
2582}
2583
2584
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002585Code::Flags Code::flags() {
2586 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2587}
2588
2589
2590void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002591 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002592 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002593 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2594 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002595 ExtractArgumentsCountFromFlags(flags) >= 0);
2596 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2597}
2598
2599
2600Code::Kind Code::kind() {
2601 return ExtractKindFromFlags(flags());
2602}
2603
2604
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002605InLoopFlag Code::ic_in_loop() {
2606 return ExtractICInLoopFromFlags(flags());
2607}
2608
2609
kasper.lund7276f142008-07-30 08:49:36 +00002610InlineCacheState Code::ic_state() {
2611 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002612 // Only allow uninitialized or debugger states for non-IC code
2613 // objects. This is used in the debugger to determine whether or not
2614 // a call to code object has been replaced with a debug break call.
2615 ASSERT(is_inline_cache_stub() ||
2616 result == UNINITIALIZED ||
2617 result == DEBUG_BREAK ||
2618 result == DEBUG_PREPARE_STEP_IN);
2619 return result;
2620}
2621
2622
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002623Code::ExtraICState Code::extra_ic_state() {
2624 ASSERT(is_inline_cache_stub());
2625 return ExtractExtraICStateFromFlags(flags());
2626}
2627
2628
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002629PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002630 return ExtractTypeFromFlags(flags());
2631}
2632
2633
2634int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002635 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002636 return ExtractArgumentsCountFromFlags(flags());
2637}
2638
2639
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002640int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002641 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002642 kind() == UNARY_OP_IC ||
2643 kind() == BINARY_OP_IC ||
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002644 kind() == COMPARE_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002645 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002646}
2647
2648
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002649void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002650 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002651 kind() == UNARY_OP_IC ||
2652 kind() == BINARY_OP_IC ||
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002653 kind() == COMPARE_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002654 ASSERT(0 <= major && major < 256);
2655 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002656}
2657
2658
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002659bool Code::optimizable() {
2660 ASSERT(kind() == FUNCTION);
2661 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2662}
2663
2664
2665void Code::set_optimizable(bool value) {
2666 ASSERT(kind() == FUNCTION);
2667 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2668}
2669
2670
2671bool Code::has_deoptimization_support() {
2672 ASSERT(kind() == FUNCTION);
2673 return READ_BYTE_FIELD(this, kHasDeoptimizationSupportOffset) == 1;
2674}
2675
2676
2677void Code::set_has_deoptimization_support(bool value) {
2678 ASSERT(kind() == FUNCTION);
2679 WRITE_BYTE_FIELD(this, kHasDeoptimizationSupportOffset, value ? 1 : 0);
2680}
2681
2682
2683int Code::allow_osr_at_loop_nesting_level() {
2684 ASSERT(kind() == FUNCTION);
2685 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
2686}
2687
2688
2689void Code::set_allow_osr_at_loop_nesting_level(int level) {
2690 ASSERT(kind() == FUNCTION);
2691 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
2692 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
2693}
2694
2695
2696unsigned Code::stack_slots() {
2697 ASSERT(kind() == OPTIMIZED_FUNCTION);
2698 return READ_UINT32_FIELD(this, kStackSlotsOffset);
2699}
2700
2701
2702void Code::set_stack_slots(unsigned slots) {
2703 ASSERT(kind() == OPTIMIZED_FUNCTION);
2704 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
2705}
2706
2707
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002708unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002709 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002710 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002711}
2712
2713
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002714void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002715 ASSERT(kind() == OPTIMIZED_FUNCTION);
2716 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002717 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002718}
2719
2720
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002721unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002722 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002723 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002724}
2725
2726
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002727void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002728 ASSERT(kind() == FUNCTION);
2729 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002730 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002731}
2732
2733
2734CheckType Code::check_type() {
2735 ASSERT(is_call_stub() || is_keyed_call_stub());
2736 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
2737 return static_cast<CheckType>(type);
2738}
2739
2740
2741void Code::set_check_type(CheckType value) {
2742 ASSERT(is_call_stub() || is_keyed_call_stub());
2743 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
2744}
2745
2746
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002747ExternalArrayType Code::external_array_type() {
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002748 ASSERT(is_keyed_load_stub() || is_keyed_store_stub());
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002749 byte type = READ_BYTE_FIELD(this, kExternalArrayTypeOffset);
2750 return static_cast<ExternalArrayType>(type);
2751}
2752
2753
2754void Code::set_external_array_type(ExternalArrayType value) {
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002755 ASSERT(is_keyed_load_stub() || is_keyed_store_stub());
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002756 WRITE_BYTE_FIELD(this, kExternalArrayTypeOffset, value);
2757}
2758
2759
danno@chromium.org40cb8782011-05-25 07:58:50 +00002760byte Code::unary_op_type() {
2761 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002762 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
2763}
2764
2765
danno@chromium.org40cb8782011-05-25 07:58:50 +00002766void Code::set_unary_op_type(byte value) {
2767 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002768 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
2769}
2770
2771
danno@chromium.org40cb8782011-05-25 07:58:50 +00002772byte Code::binary_op_type() {
2773 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002774 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
2775}
2776
2777
danno@chromium.org40cb8782011-05-25 07:58:50 +00002778void Code::set_binary_op_type(byte value) {
2779 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002780 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
2781}
2782
2783
danno@chromium.org40cb8782011-05-25 07:58:50 +00002784byte Code::binary_op_result_type() {
2785 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002786 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
2787}
2788
2789
danno@chromium.org40cb8782011-05-25 07:58:50 +00002790void Code::set_binary_op_result_type(byte value) {
2791 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002792 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
2793}
2794
2795
2796byte Code::compare_state() {
2797 ASSERT(is_compare_ic_stub());
2798 return READ_BYTE_FIELD(this, kCompareStateOffset);
2799}
2800
2801
2802void Code::set_compare_state(byte value) {
2803 ASSERT(is_compare_ic_stub());
2804 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
2805}
2806
2807
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002808bool Code::is_inline_cache_stub() {
2809 Kind kind = this->kind();
2810 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2811}
2812
2813
2814Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002815 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002816 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002817 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002818 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002819 int argc,
2820 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002821 // Extra IC state is only allowed for call IC stubs or for store IC
2822 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002823 ASSERT(extra_ic_state == kNoExtraICState ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002824 (kind == CALL_IC) ||
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00002825 (kind == STORE_IC) ||
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002826 (kind == KEYED_STORE_IC));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002827 // Compute the bit mask.
2828 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002829 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002830 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002831 bits |= type << kFlagsTypeShift;
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002832 bits |= extra_ic_state << kFlagsExtraICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002833 bits |= argc << kFlagsArgumentsCountShift;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002834 if (holder == PROTOTYPE_MAP) bits |= kFlagsCacheInPrototypeMapMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002835 // Cast to flags and validate result before returning it.
2836 Flags result = static_cast<Flags>(bits);
2837 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002838 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002839 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002840 ASSERT(ExtractTypeFromFlags(result) == type);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002841 ASSERT(ExtractExtraICStateFromFlags(result) == extra_ic_state);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002842 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2843 return result;
2844}
2845
2846
2847Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2848 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002849 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002850 InlineCacheHolderFlag holder,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002851 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002852 int argc) {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002853 return ComputeFlags(
2854 kind, in_loop, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002855}
2856
2857
2858Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2859 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2860 return static_cast<Kind>(bits);
2861}
2862
2863
kasper.lund7276f142008-07-30 08:49:36 +00002864InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2865 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002866 return static_cast<InlineCacheState>(bits);
2867}
2868
2869
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002870Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
2871 int bits = (flags & kFlagsExtraICStateMask) >> kFlagsExtraICStateShift;
2872 return static_cast<ExtraICState>(bits);
2873}
2874
2875
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002876InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2877 int bits = (flags & kFlagsICInLoopMask);
2878 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
2879}
2880
2881
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002882PropertyType Code::ExtractTypeFromFlags(Flags flags) {
2883 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2884 return static_cast<PropertyType>(bits);
2885}
2886
2887
2888int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2889 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2890}
2891
2892
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002893InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
2894 int bits = (flags & kFlagsCacheInPrototypeMapMask);
2895 return bits != 0 ? PROTOTYPE_MAP : OWN_MAP;
2896}
2897
2898
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002899Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2900 int bits = flags & ~kFlagsTypeMask;
2901 return static_cast<Flags>(bits);
2902}
2903
2904
ager@chromium.org8bb60582008-12-11 12:02:20 +00002905Code* Code::GetCodeFromTargetAddress(Address address) {
2906 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2907 // GetCodeFromTargetAddress might be called when marking objects during mark
2908 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2909 // Code::cast. Code::cast does not work when the object's map is
2910 // marked.
2911 Code* result = reinterpret_cast<Code*>(code);
2912 return result;
2913}
2914
2915
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002916Isolate* Map::isolate() {
2917 return heap()->isolate();
2918}
2919
2920
2921Heap* Map::heap() {
2922 // NOTE: address() helper is not used to save one instruction.
2923 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
2924 ASSERT(heap != NULL);
2925 ASSERT(heap->isolate() == Isolate::Current());
2926 return heap;
2927}
2928
2929
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00002930Heap* Code::heap() {
2931 // NOTE: address() helper is not used to save one instruction.
2932 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
2933 ASSERT(heap != NULL);
2934 ASSERT(heap->isolate() == Isolate::Current());
2935 return heap;
2936}
2937
2938
2939Isolate* Code::isolate() {
2940 return heap()->isolate();
2941}
2942
2943
2944Heap* JSGlobalPropertyCell::heap() {
2945 // NOTE: address() helper is not used to save one instruction.
2946 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
2947 ASSERT(heap != NULL);
2948 ASSERT(heap->isolate() == Isolate::Current());
2949 return heap;
2950}
2951
2952
2953Isolate* JSGlobalPropertyCell::isolate() {
2954 return heap()->isolate();
2955}
2956
2957
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002958Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
2959 return HeapObject::
2960 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
2961}
2962
2963
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002964Object* Map::prototype() {
2965 return READ_FIELD(this, kPrototypeOffset);
2966}
2967
2968
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002969void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00002970 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002971 WRITE_FIELD(this, kPrototypeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002972 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002973}
2974
2975
lrn@chromium.org303ada72010-10-27 09:33:13 +00002976MaybeObject* Map::GetFastElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002977 if (has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00002978 Object* obj;
2979 { MaybeObject* maybe_obj = CopyDropTransitions();
2980 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2981 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002982 Map* new_map = Map::cast(obj);
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00002983 new_map->set_elements_kind(JSObject::FAST_ELEMENTS);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002984 isolate()->counters()->map_slow_to_fast_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002985 return new_map;
2986}
2987
2988
lrn@chromium.org303ada72010-10-27 09:33:13 +00002989MaybeObject* Map::GetSlowElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002990 if (!has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00002991 Object* obj;
2992 { MaybeObject* maybe_obj = CopyDropTransitions();
2993 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
2994 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002995 Map* new_map = Map::cast(obj);
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00002996 new_map->set_elements_kind(JSObject::DICTIONARY_ELEMENTS);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002997 isolate()->counters()->map_fast_to_slow_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00002998 return new_map;
2999}
3000
3001
danno@chromium.org40cb8782011-05-25 07:58:50 +00003002DescriptorArray* Map::instance_descriptors() {
3003 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3004 if (object->IsSmi()) {
3005 return HEAP->empty_descriptor_array();
3006 } else {
3007 return DescriptorArray::cast(object);
3008 }
3009}
3010
3011
3012void Map::init_instance_descriptors() {
3013 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3014}
3015
3016
3017void Map::clear_instance_descriptors() {
3018 Object* object = READ_FIELD(this,
3019 kInstanceDescriptorsOrBitField3Offset);
3020 if (!object->IsSmi()) {
3021 WRITE_FIELD(
3022 this,
3023 kInstanceDescriptorsOrBitField3Offset,
3024 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3025 }
3026}
3027
3028
3029void Map::set_instance_descriptors(DescriptorArray* value,
3030 WriteBarrierMode mode) {
3031 Object* object = READ_FIELD(this,
3032 kInstanceDescriptorsOrBitField3Offset);
3033 if (value == isolate()->heap()->empty_descriptor_array()) {
3034 clear_instance_descriptors();
3035 return;
3036 } else {
3037 if (object->IsSmi()) {
3038 value->set_bit_field3_storage(Smi::cast(object)->value());
3039 } else {
3040 value->set_bit_field3_storage(
3041 DescriptorArray::cast(object)->bit_field3_storage());
3042 }
3043 }
3044 ASSERT(!is_shared());
3045 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
3046 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3047 this,
3048 kInstanceDescriptorsOrBitField3Offset,
3049 mode);
3050}
3051
3052
3053int Map::bit_field3() {
3054 Object* object = READ_FIELD(this,
3055 kInstanceDescriptorsOrBitField3Offset);
3056 if (object->IsSmi()) {
3057 return Smi::cast(object)->value();
3058 } else {
3059 return DescriptorArray::cast(object)->bit_field3_storage();
3060 }
3061}
3062
3063
3064void Map::set_bit_field3(int value) {
3065 ASSERT(Smi::IsValid(value));
3066 Object* object = READ_FIELD(this,
3067 kInstanceDescriptorsOrBitField3Offset);
3068 if (object->IsSmi()) {
3069 WRITE_FIELD(this,
3070 kInstanceDescriptorsOrBitField3Offset,
3071 Smi::FromInt(value));
3072 } else {
3073 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3074 }
3075}
3076
3077
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003078ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003079ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003080ACCESSORS(Map, constructor, Object, kConstructorOffset)
3081
3082ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
3083ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003084ACCESSORS_GCSAFE(JSFunction, next_function_link, Object,
3085 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003086
3087ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3088ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003089ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003090
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003091ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003092
3093ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3094ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3095ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3096ACCESSORS(AccessorInfo, name, Object, kNameOffset)
3097ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
3098
3099ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3100ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3101ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3102
3103ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3104ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3105ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3106ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3107ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3108ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3109
3110ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3111ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3112
3113ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3114ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3115
3116ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3117ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003118ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3119 kPropertyAccessorsOffset)
3120ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3121 kPrototypeTemplateOffset)
3122ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3123ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3124 kNamedPropertyHandlerOffset)
3125ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3126 kIndexedPropertyHandlerOffset)
3127ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3128 kInstanceTemplateOffset)
3129ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3130ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003131ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3132 kInstanceCallHandlerOffset)
3133ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3134 kAccessCheckInfoOffset)
3135ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
3136
3137ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003138ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3139 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003140
3141ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3142ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3143
3144ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3145
3146ACCESSORS(Script, source, Object, kSourceOffset)
3147ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003148ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003149ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3150ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003151ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003152ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003153ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003154ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003155ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003156ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003157ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003158ACCESSORS(Script, eval_from_instructions_offset, Smi,
3159 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003160
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003161#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003162ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3163ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3164ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3165ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3166
3167ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3168ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3169ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3170ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003171#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003172
3173ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003174ACCESSORS_GCSAFE(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3175ACCESSORS_GCSAFE(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003176ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3177 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003178ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003179ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3180ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003181ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003182ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3183 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003184
3185BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3186 kHiddenPrototypeBit)
3187BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3188BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3189 kNeedsAccessCheckBit)
3190BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3191 kIsExpressionBit)
3192BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3193 kIsTopLevelBit)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003194BOOL_GETTER(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003195 has_only_simple_this_property_assignments,
3196 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003197BOOL_ACCESSORS(SharedFunctionInfo,
3198 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003199 allows_lazy_compilation,
3200 kAllowLazyCompilation)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003201
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003202
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003203#if V8_HOST_ARCH_32_BIT
3204SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3205SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003206 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003207SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003208 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003209SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3210SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003211 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003212SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3213SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003214 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003215SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003216 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003217SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003218 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003219SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003220#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003221
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003222#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003223 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003224 int holder::name() { \
3225 int value = READ_INT_FIELD(this, offset); \
3226 ASSERT(kHeapObjectTag == 1); \
3227 ASSERT((value & kHeapObjectTag) == 0); \
3228 return value >> 1; \
3229 } \
3230 void holder::set_##name(int value) { \
3231 ASSERT(kHeapObjectTag == 1); \
3232 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3233 (value & 0xC0000000) == 0x000000000); \
3234 WRITE_INT_FIELD(this, \
3235 offset, \
3236 (value << 1) & ~kHeapObjectTag); \
3237 }
3238
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003239#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3240 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003241 INT_ACCESSORS(holder, name, offset)
3242
3243
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003244PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003245PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3246 formal_parameter_count,
3247 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003248
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003249PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3250 expected_nof_properties,
3251 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003252PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3253
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003254PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3255PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3256 start_position_and_type,
3257 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003258
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003259PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3260 function_token_position,
3261 kFunctionTokenPositionOffset)
3262PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3263 compiler_hints,
3264 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003265
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003266PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3267 this_property_assignments_count,
3268 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003269PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003270#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003271
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003272
3273int SharedFunctionInfo::construction_count() {
3274 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3275}
3276
3277
3278void SharedFunctionInfo::set_construction_count(int value) {
3279 ASSERT(0 <= value && value < 256);
3280 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3281}
3282
3283
3284bool SharedFunctionInfo::live_objects_may_exist() {
3285 return (compiler_hints() & (1 << kLiveObjectsMayExist)) != 0;
3286}
3287
3288
3289void SharedFunctionInfo::set_live_objects_may_exist(bool value) {
3290 if (value) {
3291 set_compiler_hints(compiler_hints() | (1 << kLiveObjectsMayExist));
3292 } else {
3293 set_compiler_hints(compiler_hints() & ~(1 << kLiveObjectsMayExist));
3294 }
3295}
3296
3297
3298bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003299 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003300}
3301
3302
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003303bool SharedFunctionInfo::optimization_disabled() {
3304 return BooleanBit::get(compiler_hints(), kOptimizationDisabled);
3305}
3306
3307
3308void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3309 set_compiler_hints(BooleanBit::set(compiler_hints(),
3310 kOptimizationDisabled,
3311 disable));
3312 // If disabling optimizations we reflect that in the code object so
3313 // it will not be counted as optimizable code.
3314 if ((code()->kind() == Code::FUNCTION) && disable) {
3315 code()->set_optimizable(false);
3316 }
3317}
3318
3319
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003320bool SharedFunctionInfo::strict_mode() {
3321 return BooleanBit::get(compiler_hints(), kStrictModeFunction);
3322}
3323
3324
3325void SharedFunctionInfo::set_strict_mode(bool value) {
3326 set_compiler_hints(BooleanBit::set(compiler_hints(),
3327 kStrictModeFunction,
3328 value));
3329}
3330
3331
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00003332bool SharedFunctionInfo::native() {
3333 return BooleanBit::get(compiler_hints(), kNative);
ricow@chromium.org6fe7a8e2011-05-13 07:57:29 +00003334}
3335
3336
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00003337void SharedFunctionInfo::set_native(bool value) {
ricow@chromium.org6fe7a8e2011-05-13 07:57:29 +00003338 set_compiler_hints(BooleanBit::set(compiler_hints(),
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00003339 kNative,
ricow@chromium.org6fe7a8e2011-05-13 07:57:29 +00003340 value));
3341}
3342
3343
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003344ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3345ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3346
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003347ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3348
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003349bool Script::HasValidSource() {
3350 Object* src = this->source();
3351 if (!src->IsString()) return true;
3352 String* src_str = String::cast(src);
3353 if (!StringShape(src_str).IsExternal()) return true;
3354 if (src_str->IsAsciiRepresentation()) {
3355 return ExternalAsciiString::cast(src)->resource() != NULL;
3356 } else if (src_str->IsTwoByteRepresentation()) {
3357 return ExternalTwoByteString::cast(src)->resource() != NULL;
3358 }
3359 return true;
3360}
3361
3362
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003363void SharedFunctionInfo::DontAdaptArguments() {
3364 ASSERT(code()->kind() == Code::BUILTIN);
3365 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3366}
3367
3368
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003369int SharedFunctionInfo::start_position() {
3370 return start_position_and_type() >> kStartPositionShift;
3371}
3372
3373
3374void SharedFunctionInfo::set_start_position(int start_position) {
3375 set_start_position_and_type((start_position << kStartPositionShift)
3376 | (start_position_and_type() & ~kStartPositionMask));
3377}
3378
3379
3380Code* SharedFunctionInfo::code() {
3381 return Code::cast(READ_FIELD(this, kCodeOffset));
3382}
3383
3384
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003385Code* SharedFunctionInfo::unchecked_code() {
3386 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3387}
3388
3389
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003390void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003391 WRITE_FIELD(this, kCodeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003392 ASSERT(!Isolate::Current()->heap()->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003393}
3394
3395
ager@chromium.orgb5737492010-07-15 09:29:43 +00003396SerializedScopeInfo* SharedFunctionInfo::scope_info() {
3397 return reinterpret_cast<SerializedScopeInfo*>(
3398 READ_FIELD(this, kScopeInfoOffset));
3399}
3400
3401
3402void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
3403 WriteBarrierMode mode) {
3404 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003405 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kScopeInfoOffset, mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003406}
3407
3408
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003409Smi* SharedFunctionInfo::deopt_counter() {
3410 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3411}
3412
3413
3414void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3415 WRITE_FIELD(this, kDeoptCounterOffset, value);
3416}
3417
3418
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003419bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003420 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003421 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003422}
3423
3424
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003425bool SharedFunctionInfo::IsApiFunction() {
3426 return function_data()->IsFunctionTemplateInfo();
3427}
3428
3429
3430FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3431 ASSERT(IsApiFunction());
3432 return FunctionTemplateInfo::cast(function_data());
3433}
3434
3435
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003436bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003437 return function_data()->IsSmi();
3438}
3439
3440
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003441BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3442 ASSERT(HasBuiltinFunctionId());
3443 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003444}
3445
3446
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003447int SharedFunctionInfo::code_age() {
3448 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3449}
3450
3451
3452void SharedFunctionInfo::set_code_age(int code_age) {
3453 set_compiler_hints(compiler_hints() |
3454 ((code_age & kCodeAgeMask) << kCodeAgeShift));
3455}
3456
3457
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003458bool SharedFunctionInfo::has_deoptimization_support() {
3459 Code* code = this->code();
3460 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3461}
3462
3463
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003464bool JSFunction::IsBuiltin() {
3465 return context()->global()->IsJSBuiltinsObject();
3466}
3467
3468
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003469bool JSFunction::NeedsArgumentsAdaption() {
3470 return shared()->formal_parameter_count() !=
3471 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3472}
3473
3474
3475bool JSFunction::IsOptimized() {
3476 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3477}
3478
3479
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003480bool JSFunction::IsOptimizable() {
3481 return code()->kind() == Code::FUNCTION && code()->optimizable();
3482}
3483
3484
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003485bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003486 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003487}
3488
3489
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003490Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003491 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003492}
3493
3494
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003495Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003496 return reinterpret_cast<Code*>(
3497 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003498}
3499
3500
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003501void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00003502 // Skip the write barrier because code is never in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003503 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003504 Address entry = value->entry();
3505 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003506}
3507
3508
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003509void JSFunction::ReplaceCode(Code* code) {
3510 bool was_optimized = IsOptimized();
3511 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3512
3513 set_code(code);
3514
3515 // Add/remove the function from the list of optimized functions for this
3516 // context based on the state change.
3517 if (!was_optimized && is_optimized) {
3518 context()->global_context()->AddOptimizedFunction(this);
3519 }
3520 if (was_optimized && !is_optimized) {
3521 context()->global_context()->RemoveOptimizedFunction(this);
3522 }
3523}
3524
3525
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003526Context* JSFunction::context() {
3527 return Context::cast(READ_FIELD(this, kContextOffset));
3528}
3529
3530
3531Object* JSFunction::unchecked_context() {
3532 return READ_FIELD(this, kContextOffset);
3533}
3534
3535
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003536SharedFunctionInfo* JSFunction::unchecked_shared() {
3537 return reinterpret_cast<SharedFunctionInfo*>(
3538 READ_FIELD(this, kSharedFunctionInfoOffset));
3539}
3540
3541
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003542void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003543 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003544 WRITE_FIELD(this, kContextOffset, value);
3545 WRITE_BARRIER(this, kContextOffset);
3546}
3547
3548ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3549 kPrototypeOrInitialMapOffset)
3550
3551
3552Map* JSFunction::initial_map() {
3553 return Map::cast(prototype_or_initial_map());
3554}
3555
3556
3557void JSFunction::set_initial_map(Map* value) {
3558 set_prototype_or_initial_map(value);
3559}
3560
3561
3562bool JSFunction::has_initial_map() {
3563 return prototype_or_initial_map()->IsMap();
3564}
3565
3566
3567bool JSFunction::has_instance_prototype() {
3568 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3569}
3570
3571
3572bool JSFunction::has_prototype() {
3573 return map()->has_non_instance_prototype() || has_instance_prototype();
3574}
3575
3576
3577Object* JSFunction::instance_prototype() {
3578 ASSERT(has_instance_prototype());
3579 if (has_initial_map()) return initial_map()->prototype();
3580 // When there is no initial map and the prototype is a JSObject, the
3581 // initial map field is used for the prototype field.
3582 return prototype_or_initial_map();
3583}
3584
3585
3586Object* JSFunction::prototype() {
3587 ASSERT(has_prototype());
3588 // If the function's prototype property has been set to a non-JSObject
3589 // value, that value is stored in the constructor field of the map.
3590 if (map()->has_non_instance_prototype()) return map()->constructor();
3591 return instance_prototype();
3592}
3593
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003594bool JSFunction::should_have_prototype() {
3595 return map()->function_with_prototype();
3596}
3597
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003598
3599bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003600 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003601}
3602
3603
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003604int JSFunction::NumberOfLiterals() {
3605 return literals()->length();
3606}
3607
3608
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003609Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003610 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003611 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003612}
3613
3614
3615void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3616 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003617 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003618 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
3619 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
3620}
3621
3622
3623Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003624 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003625 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3626}
3627
3628
3629void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3630 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003631 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003632 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003633 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003634}
3635
3636
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003637ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
3638
3639
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003640Address Foreign::address() {
3641 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003642}
3643
3644
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003645void Foreign::set_address(Address value) {
3646 WRITE_INTPTR_FIELD(this, kAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003647}
3648
3649
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003650ACCESSORS(JSValue, value, Object, kValueOffset)
3651
3652
3653JSValue* JSValue::cast(Object* obj) {
3654 ASSERT(obj->IsJSValue());
3655 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3656 return reinterpret_cast<JSValue*>(obj);
3657}
3658
3659
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003660ACCESSORS(JSMessageObject, type, String, kTypeOffset)
3661ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
3662ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
3663ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
3664ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
3665SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
3666SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
3667
3668
3669JSMessageObject* JSMessageObject::cast(Object* obj) {
3670 ASSERT(obj->IsJSMessageObject());
3671 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
3672 return reinterpret_cast<JSMessageObject*>(obj);
3673}
3674
3675
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003676INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003677ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003678ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003679ACCESSORS(Code, next_code_flushing_candidate,
3680 Object, kNextCodeFlushingCandidateOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003681
3682
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003683byte* Code::instruction_start() {
3684 return FIELD_ADDR(this, kHeaderSize);
3685}
3686
3687
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003688byte* Code::instruction_end() {
3689 return instruction_start() + instruction_size();
3690}
3691
3692
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003693int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003694 return RoundUp(instruction_size(), kObjectAlignment);
3695}
3696
3697
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003698FixedArray* Code::unchecked_deoptimization_data() {
3699 return reinterpret_cast<FixedArray*>(
3700 READ_FIELD(this, kDeoptimizationDataOffset));
3701}
3702
3703
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003704ByteArray* Code::unchecked_relocation_info() {
3705 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003706}
3707
3708
3709byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003710 return unchecked_relocation_info()->GetDataStartAddress();
3711}
3712
3713
3714int Code::relocation_size() {
3715 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003716}
3717
3718
3719byte* Code::entry() {
3720 return instruction_start();
3721}
3722
3723
3724bool Code::contains(byte* pc) {
3725 return (instruction_start() <= pc) &&
ricow@chromium.org65fae842010-08-25 15:26:24 +00003726 (pc <= instruction_start() + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003727}
3728
3729
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003730ACCESSORS(JSArray, length, Object, kLengthOffset)
3731
3732
ager@chromium.org236ad962008-09-25 09:45:57 +00003733ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00003734
3735
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003736JSRegExp::Type JSRegExp::TypeTag() {
3737 Object* data = this->data();
3738 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
3739 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
3740 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00003741}
3742
3743
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00003744int JSRegExp::CaptureCount() {
3745 switch (TypeTag()) {
3746 case ATOM:
3747 return 0;
3748 case IRREGEXP:
3749 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
3750 default:
3751 UNREACHABLE();
3752 return -1;
3753 }
3754}
3755
3756
ager@chromium.orga74f0da2008-12-03 16:05:52 +00003757JSRegExp::Flags JSRegExp::GetFlags() {
3758 ASSERT(this->data()->IsFixedArray());
3759 Object* data = this->data();
3760 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
3761 return Flags(smi->value());
3762}
3763
3764
3765String* JSRegExp::Pattern() {
3766 ASSERT(this->data()->IsFixedArray());
3767 Object* data = this->data();
3768 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
3769 return pattern;
3770}
3771
3772
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003773Object* JSRegExp::DataAt(int index) {
3774 ASSERT(TypeTag() != NOT_COMPILED);
3775 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00003776}
3777
3778
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003779void JSRegExp::SetDataAt(int index, Object* value) {
3780 ASSERT(TypeTag() != NOT_COMPILED);
3781 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
3782 FixedArray::cast(data())->set(index, value);
3783}
3784
3785
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003786JSObject::ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003787 ElementsKind kind = map()->elements_kind();
3788 ASSERT((kind == FAST_ELEMENTS &&
3789 (elements()->map() == GetHeap()->fixed_array_map() ||
3790 elements()->map() == GetHeap()->fixed_cow_array_map())) ||
3791 (kind == DICTIONARY_ELEMENTS &&
3792 elements()->IsFixedArray() &&
3793 elements()->IsDictionary()) ||
3794 (kind > DICTIONARY_ELEMENTS));
3795 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003796}
3797
3798
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003799bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003800 return GetElementsKind() == FAST_ELEMENTS;
3801}
3802
3803
3804bool JSObject::HasDictionaryElements() {
3805 return GetElementsKind() == DICTIONARY_ELEMENTS;
3806}
3807
3808
ager@chromium.org3811b432009-10-28 14:53:37 +00003809bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003810 HeapObject* array = elements();
3811 ASSERT(array != NULL);
3812 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00003813}
3814
3815
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003816#define EXTERNAL_ELEMENTS_CHECK(name, type) \
3817bool JSObject::HasExternal##name##Elements() { \
3818 HeapObject* array = elements(); \
3819 ASSERT(array != NULL); \
3820 if (!array->IsHeapObject()) \
3821 return false; \
3822 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00003823}
3824
3825
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003826EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
3827EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
3828EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
3829EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
3830 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
3831EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
3832EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
3833 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
3834EXTERNAL_ELEMENTS_CHECK(Float,
3835 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003836EXTERNAL_ELEMENTS_CHECK(Double,
3837 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003838EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00003839
3840
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003841bool JSObject::HasNamedInterceptor() {
3842 return map()->has_named_interceptor();
3843}
3844
3845
3846bool JSObject::HasIndexedInterceptor() {
3847 return map()->has_indexed_interceptor();
3848}
3849
3850
ager@chromium.org5c838252010-02-19 08:53:10 +00003851bool JSObject::AllowsSetElementsLength() {
3852 bool result = elements()->IsFixedArray();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003853 ASSERT(result == !HasExternalArrayElements());
ager@chromium.org5c838252010-02-19 08:53:10 +00003854 return result;
3855}
3856
3857
lrn@chromium.org303ada72010-10-27 09:33:13 +00003858MaybeObject* JSObject::EnsureWritableFastElements() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003859 ASSERT(HasFastElements());
3860 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003861 Isolate* isolate = GetIsolate();
3862 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003863 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003864 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
3865 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00003866 if (!maybe_writable_elems->ToObject(&writable_elems)) {
3867 return maybe_writable_elems;
3868 }
3869 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003870 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003871 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003872 return writable_elems;
3873}
3874
3875
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003876StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003877 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003878 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003879}
3880
3881
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003882NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003883 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00003884 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003885}
3886
3887
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003888bool String::IsHashFieldComputed(uint32_t field) {
3889 return (field & kHashNotComputedMask) == 0;
3890}
3891
3892
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003893bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003894 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003895}
3896
3897
3898uint32_t String::Hash() {
3899 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003900 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003901 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003902 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003903 return ComputeAndSetHash();
3904}
3905
3906
ager@chromium.org7c537e22008-10-16 08:43:32 +00003907StringHasher::StringHasher(int length)
3908 : length_(length),
3909 raw_running_hash_(0),
3910 array_index_(0),
3911 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
3912 is_first_char_(true),
3913 is_valid_(true) { }
3914
3915
3916bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003917 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00003918}
3919
3920
3921void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003922 // Use the Jenkins one-at-a-time hash function to update the hash
3923 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003924 raw_running_hash_ += c;
3925 raw_running_hash_ += (raw_running_hash_ << 10);
3926 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003927 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003928 if (is_array_index_) {
3929 if (c < '0' || c > '9') {
3930 is_array_index_ = false;
3931 } else {
3932 int d = c - '0';
3933 if (is_first_char_) {
3934 is_first_char_ = false;
3935 if (c == '0' && length_ > 1) {
3936 is_array_index_ = false;
3937 return;
3938 }
3939 }
3940 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
3941 is_array_index_ = false;
3942 } else {
3943 array_index_ = array_index_ * 10 + d;
3944 }
3945 }
3946 }
3947}
3948
3949
3950void StringHasher::AddCharacterNoIndex(uc32 c) {
3951 ASSERT(!is_array_index());
3952 raw_running_hash_ += c;
3953 raw_running_hash_ += (raw_running_hash_ << 10);
3954 raw_running_hash_ ^= (raw_running_hash_ >> 6);
3955}
3956
3957
3958uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003959 // Get the calculated raw hash value and do some more bit ops to distribute
3960 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00003961 uint32_t result = raw_running_hash_;
3962 result += (result << 3);
3963 result ^= (result >> 11);
3964 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00003965 if (result == 0) {
3966 result = 27;
3967 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00003968 return result;
3969}
3970
3971
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00003972template <typename schar>
3973uint32_t HashSequentialString(const schar* chars, int length) {
3974 StringHasher hasher(length);
3975 if (!hasher.has_trivial_hash()) {
3976 int i;
3977 for (i = 0; hasher.is_array_index() && (i < length); i++) {
3978 hasher.AddCharacter(chars[i]);
3979 }
3980 for (; i < length; i++) {
3981 hasher.AddCharacterNoIndex(chars[i]);
3982 }
3983 }
3984 return hasher.GetHashField();
3985}
3986
3987
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003988bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00003989 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00003990 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
3991 return false;
3992 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003993 return SlowAsArrayIndex(index);
3994}
3995
3996
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00003997Object* JSReceiver::GetPrototype() {
3998 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003999}
4000
4001
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004002PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004003 return GetPropertyAttributeWithReceiver(this, key);
4004}
4005
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004006// TODO(504): this may be useful in other places too where JSGlobalProxy
4007// is used.
4008Object* JSObject::BypassGlobalProxy() {
4009 if (IsJSGlobalProxy()) {
4010 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004011 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004012 ASSERT(proto->IsJSGlobalObject());
4013 return proto;
4014 }
4015 return this;
4016}
4017
4018
4019bool JSObject::HasHiddenPropertiesObject() {
4020 ASSERT(!IsJSGlobalProxy());
4021 return GetPropertyAttributePostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004022 GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004023 false) != ABSENT;
4024}
4025
4026
4027Object* JSObject::GetHiddenPropertiesObject() {
4028 ASSERT(!IsJSGlobalProxy());
4029 PropertyAttributes attributes;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004030 // You can't install a getter on a property indexed by the hidden symbol,
4031 // so we can be sure that GetLocalPropertyPostInterceptor returns a real
4032 // object.
4033 Object* result =
4034 GetLocalPropertyPostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004035 GetHeap()->hidden_symbol(),
lrn@chromium.org303ada72010-10-27 09:33:13 +00004036 &attributes)->ToObjectUnchecked();
4037 return result;
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004038}
4039
4040
lrn@chromium.org303ada72010-10-27 09:33:13 +00004041MaybeObject* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004042 ASSERT(!IsJSGlobalProxy());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004043 return SetPropertyPostInterceptor(GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004044 hidden_obj,
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00004045 DONT_ENUM,
4046 kNonStrictMode);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004047}
4048
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004049
4050bool JSObject::HasElement(uint32_t index) {
4051 return HasElementWithReceiver(this, index);
4052}
4053
4054
4055bool AccessorInfo::all_can_read() {
4056 return BooleanBit::get(flag(), kAllCanReadBit);
4057}
4058
4059
4060void AccessorInfo::set_all_can_read(bool value) {
4061 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4062}
4063
4064
4065bool AccessorInfo::all_can_write() {
4066 return BooleanBit::get(flag(), kAllCanWriteBit);
4067}
4068
4069
4070void AccessorInfo::set_all_can_write(bool value) {
4071 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4072}
4073
4074
ager@chromium.org870a0b62008-11-04 11:43:05 +00004075bool AccessorInfo::prohibits_overwriting() {
4076 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4077}
4078
4079
4080void AccessorInfo::set_prohibits_overwriting(bool value) {
4081 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4082}
4083
4084
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004085PropertyAttributes AccessorInfo::property_attributes() {
4086 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4087}
4088
4089
4090void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
4091 ASSERT(AttributesField::is_valid(attributes));
4092 int rest_value = flag()->value() & ~AttributesField::mask();
4093 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
4094}
4095
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004096
4097template<typename Shape, typename Key>
4098void Dictionary<Shape, Key>::SetEntry(int entry,
4099 Object* key,
4100 Object* value) {
4101 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4102}
4103
4104
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004105template<typename Shape, typename Key>
4106void Dictionary<Shape, Key>::SetEntry(int entry,
4107 Object* key,
4108 Object* value,
4109 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004110 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004111 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004112 AssertNoAllocation no_gc;
4113 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004114 FixedArray::set(index, key, mode);
4115 FixedArray::set(index+1, value, mode);
4116 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004117}
4118
4119
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004120bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4121 ASSERT(other->IsNumber());
4122 return key == static_cast<uint32_t>(other->Number());
4123}
4124
4125
4126uint32_t NumberDictionaryShape::Hash(uint32_t key) {
4127 return ComputeIntegerHash(key);
4128}
4129
4130
4131uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
4132 ASSERT(other->IsNumber());
4133 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
4134}
4135
4136
4137MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4138 return Isolate::Current()->heap()->NumberFromUint32(key);
4139}
4140
4141
4142bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4143 // We know that all entries in a hash table had their hash keys created.
4144 // Use that knowledge to have fast failure.
4145 if (key->Hash() != String::cast(other)->Hash()) return false;
4146 return key->Equals(String::cast(other));
4147}
4148
4149
4150uint32_t StringDictionaryShape::Hash(String* key) {
4151 return key->Hash();
4152}
4153
4154
4155uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4156 return String::cast(other)->Hash();
4157}
4158
4159
4160MaybeObject* StringDictionaryShape::AsObject(String* key) {
4161 return key;
4162}
4163
4164
4165void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004166 // No write barrier is needed since empty_fixed_array is not in new space.
4167 // Please note this function is used during marking:
4168 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004169 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4170 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004171}
4172
4173
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004174void JSArray::EnsureSize(int required_size) {
4175 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004176 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004177 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4178 if (elts->length() < required_size) {
4179 // Doubling in size would be overkill, but leave some slack to avoid
4180 // constantly growing.
4181 Expand(required_size + (required_size >> 3));
4182 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004183 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004184 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4185 // Expand will allocate a new backing store in new space even if the size
4186 // we asked for isn't larger than what we had before.
4187 Expand(required_size);
4188 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004189}
4190
4191
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004192void JSArray::set_length(Smi* length) {
4193 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4194}
4195
4196
ager@chromium.org7c537e22008-10-16 08:43:32 +00004197void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004198 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004199 set_elements(storage);
4200}
4201
4202
lrn@chromium.org303ada72010-10-27 09:33:13 +00004203MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004204 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004205 return GetHeap()->CopyFixedArray(this);
4206}
4207
4208
4209Relocatable::Relocatable(Isolate* isolate) {
4210 ASSERT(isolate == Isolate::Current());
4211 isolate_ = isolate;
4212 prev_ = isolate->relocatable_top();
4213 isolate->set_relocatable_top(this);
4214}
4215
4216
4217Relocatable::~Relocatable() {
4218 ASSERT(isolate_ == Isolate::Current());
4219 ASSERT_EQ(isolate_->relocatable_top(), this);
4220 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004221}
4222
4223
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004224int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4225 return map->instance_size();
4226}
4227
4228
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004229void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004230 v->VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004231 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004232}
4233
4234
4235template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004236void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004237 StaticVisitor::VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004238 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004239}
4240
4241
4242void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4243 typedef v8::String::ExternalAsciiStringResource Resource;
4244 v->VisitExternalAsciiString(
4245 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4246}
4247
4248
4249template<typename StaticVisitor>
4250void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4251 typedef v8::String::ExternalAsciiStringResource Resource;
4252 StaticVisitor::VisitExternalAsciiString(
4253 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4254}
4255
4256
4257void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4258 typedef v8::String::ExternalStringResource Resource;
4259 v->VisitExternalTwoByteString(
4260 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4261}
4262
4263
4264template<typename StaticVisitor>
4265void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4266 typedef v8::String::ExternalStringResource Resource;
4267 StaticVisitor::VisitExternalTwoByteString(
4268 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4269}
4270
4271#define SLOT_ADDR(obj, offset) \
4272 reinterpret_cast<Object**>((obj)->address() + offset)
4273
4274template<int start_offset, int end_offset, int size>
4275void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4276 HeapObject* obj,
4277 ObjectVisitor* v) {
4278 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4279}
4280
4281
4282template<int start_offset>
4283void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4284 int object_size,
4285 ObjectVisitor* v) {
4286 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4287}
4288
4289#undef SLOT_ADDR
4290
4291
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004292#undef CAST_ACCESSOR
4293#undef INT_ACCESSORS
4294#undef SMI_ACCESSORS
4295#undef ACCESSORS
4296#undef FIELD_ADDR
4297#undef READ_FIELD
4298#undef WRITE_FIELD
4299#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004300#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004301#undef READ_MEMADDR_FIELD
4302#undef WRITE_MEMADDR_FIELD
4303#undef READ_DOUBLE_FIELD
4304#undef WRITE_DOUBLE_FIELD
4305#undef READ_INT_FIELD
4306#undef WRITE_INT_FIELD
4307#undef READ_SHORT_FIELD
4308#undef WRITE_SHORT_FIELD
4309#undef READ_BYTE_FIELD
4310#undef WRITE_BYTE_FIELD
4311
4312
4313} } // namespace v8::internal
4314
4315#endif // V8_OBJECTS_INL_H_