blob: c579d373f7207416134bfd8d47dd7f8a539c9e90 [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
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +000038#include "elements.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000039#include "objects.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000040#include "contexts.h"
41#include "conversions-inl.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000042#include "heap.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000043#include "isolate.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000044#include "property.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000045#include "spaces.h"
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000046#include "store-buffer.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000047#include "v8memory.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000048
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000049#include "incremental-marking.h"
50
kasperl@chromium.org71affb52009-05-26 05:44:31 +000051namespace v8 {
52namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000053
54PropertyDetails::PropertyDetails(Smi* smi) {
55 value_ = smi->value();
56}
57
58
59Smi* PropertyDetails::AsSmi() {
60 return Smi::FromInt(value_);
61}
62
63
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000064PropertyDetails PropertyDetails::AsDeleted() {
ager@chromium.org378b34e2011-01-28 08:04:38 +000065 Smi* smi = Smi::FromInt(value_ | DeletedField::encode(1));
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000066 return PropertyDetails(smi);
67}
68
69
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000070#define CAST_ACCESSOR(type) \
71 type* type::cast(Object* object) { \
72 ASSERT(object->Is##type()); \
73 return reinterpret_cast<type*>(object); \
74 }
75
76
77#define INT_ACCESSORS(holder, name, offset) \
78 int holder::name() { return READ_INT_FIELD(this, offset); } \
79 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
80
81
82#define ACCESSORS(holder, name, type, offset) \
83 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000084 void holder::set_##name(type* value, WriteBarrierMode mode) { \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000085 WRITE_FIELD(this, offset, value); \
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +000086 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000087 }
88
89
90#define SMI_ACCESSORS(holder, name, offset) \
91 int holder::name() { \
92 Object* value = READ_FIELD(this, offset); \
93 return Smi::cast(value)->value(); \
94 } \
95 void holder::set_##name(int value) { \
96 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
97 }
98
99
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000100#define BOOL_GETTER(holder, field, name, offset) \
101 bool holder::name() { \
102 return BooleanBit::get(field(), offset); \
103 } \
104
105
106#define BOOL_ACCESSORS(holder, field, name, offset) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000107 bool holder::name() { \
108 return BooleanBit::get(field(), offset); \
109 } \
110 void holder::set_##name(bool value) { \
111 set_##field(BooleanBit::set(field(), offset, value)); \
112 }
113
114
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +0000115bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
116 // There is a constraint on the object; check.
117 if (!this->IsJSObject()) return false;
118 // Fetch the constructor function of the object.
119 Object* cons_obj = JSObject::cast(this)->map()->constructor();
120 if (!cons_obj->IsJSFunction()) return false;
121 JSFunction* fun = JSFunction::cast(cons_obj);
122 // Iterate through the chain of inheriting function templates to
123 // see if the required one occurs.
124 for (Object* type = fun->shared()->function_data();
125 type->IsFunctionTemplateInfo();
126 type = FunctionTemplateInfo::cast(type)->parent_template()) {
127 if (type == expected) return true;
128 }
129 // Didn't find the required type in the inheritance chain.
130 return false;
131}
132
133
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000134bool Object::IsSmi() {
135 return HAS_SMI_TAG(this);
136}
137
138
139bool Object::IsHeapObject() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000140 return Internals::HasHeapObjectTag(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000141}
142
143
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000144bool Object::NonFailureIsHeapObject() {
145 ASSERT(!this->IsFailure());
146 return (reinterpret_cast<intptr_t>(this) & kSmiTagMask) != 0;
147}
148
149
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000150bool Object::IsHeapNumber() {
151 return Object::IsHeapObject()
152 && HeapObject::cast(this)->map()->instance_type() == HEAP_NUMBER_TYPE;
153}
154
155
156bool Object::IsString() {
157 return Object::IsHeapObject()
158 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
159}
160
161
ricow@chromium.org9fa09672011-07-25 11:05:35 +0000162bool Object::IsSpecObject() {
163 return Object::IsHeapObject()
164 && HeapObject::cast(this)->map()->instance_type() >= FIRST_SPEC_OBJECT_TYPE;
165}
166
167
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000168bool Object::IsSpecFunction() {
169 if (!Object::IsHeapObject()) return false;
170 InstanceType type = HeapObject::cast(this)->map()->instance_type();
171 return type == JS_FUNCTION_TYPE || type == JS_FUNCTION_PROXY_TYPE;
172}
173
174
ager@chromium.org870a0b62008-11-04 11:43:05 +0000175bool Object::IsSymbol() {
176 if (!this->IsHeapObject()) return false;
177 uint32_t type = HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000178 // Because the symbol tag is non-zero and no non-string types have the
179 // symbol bit set we can test for symbols with a very simple test
180 // operation.
yangguo@chromium.org80c42ed2011-08-31 09:03:56 +0000181 STATIC_ASSERT(kSymbolTag != 0);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000182 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
183 return (type & kIsSymbolMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000184}
185
186
187bool Object::IsConsString() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000188 if (!IsString()) return false;
189 return StringShape(String::cast(this)).IsCons();
190}
191
192
193bool Object::IsSlicedString() {
194 if (!IsString()) return false;
195 return StringShape(String::cast(this)).IsSliced();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000196}
197
198
ager@chromium.org870a0b62008-11-04 11:43:05 +0000199bool Object::IsSeqString() {
200 if (!IsString()) return false;
201 return StringShape(String::cast(this)).IsSequential();
202}
203
204
205bool Object::IsSeqAsciiString() {
206 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000207 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000208 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000209}
210
211
212bool Object::IsSeqTwoByteString() {
213 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000214 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000215 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000216}
217
218
219bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000220 if (!IsString()) return false;
221 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000222}
223
224
225bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000226 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000227 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000228 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000229}
230
231
232bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000233 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000234 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000235 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000236}
237
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000238bool Object::HasValidElements() {
239 // Dictionary is covered under FixedArray.
240 return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray();
241}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000242
ager@chromium.org870a0b62008-11-04 11:43:05 +0000243StringShape::StringShape(String* str)
244 : type_(str->map()->instance_type()) {
245 set_valid();
246 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000247}
248
249
ager@chromium.org870a0b62008-11-04 11:43:05 +0000250StringShape::StringShape(Map* map)
251 : type_(map->instance_type()) {
252 set_valid();
253 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000254}
255
256
ager@chromium.org870a0b62008-11-04 11:43:05 +0000257StringShape::StringShape(InstanceType t)
258 : type_(static_cast<uint32_t>(t)) {
259 set_valid();
260 ASSERT((type_ & kIsNotStringMask) == kStringTag);
261}
262
263
264bool StringShape::IsSymbol() {
265 ASSERT(valid());
yangguo@chromium.org80c42ed2011-08-31 09:03:56 +0000266 STATIC_ASSERT(kSymbolTag != 0);
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000267 return (type_ & kIsSymbolMask) != 0;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000268}
269
270
ager@chromium.org5ec48922009-05-05 07:25:34 +0000271bool String::IsAsciiRepresentation() {
272 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000273 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000274}
275
276
ager@chromium.org5ec48922009-05-05 07:25:34 +0000277bool String::IsTwoByteRepresentation() {
278 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000279 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000280}
281
282
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000283bool String::IsAsciiRepresentationUnderneath() {
284 uint32_t type = map()->instance_type();
285 STATIC_ASSERT(kIsIndirectStringTag != 0);
286 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
287 ASSERT(IsFlat());
288 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
289 case kAsciiStringTag:
290 return true;
291 case kTwoByteStringTag:
292 return false;
293 default: // Cons or sliced string. Need to go deeper.
294 return GetUnderlying()->IsAsciiRepresentation();
295 }
296}
297
298
299bool String::IsTwoByteRepresentationUnderneath() {
300 uint32_t type = map()->instance_type();
301 STATIC_ASSERT(kIsIndirectStringTag != 0);
302 STATIC_ASSERT((kIsIndirectStringMask & kStringEncodingMask) == 0);
303 ASSERT(IsFlat());
304 switch (type & (kIsIndirectStringMask | kStringEncodingMask)) {
305 case kAsciiStringTag:
306 return false;
307 case kTwoByteStringTag:
308 return true;
309 default: // Cons or sliced string. Need to go deeper.
310 return GetUnderlying()->IsTwoByteRepresentation();
311 }
312}
313
314
ricow@chromium.org5ad5ace2010-06-23 09:06:43 +0000315bool String::HasOnlyAsciiChars() {
316 uint32_t type = map()->instance_type();
317 return (type & kStringEncodingMask) == kAsciiStringTag ||
318 (type & kAsciiDataHintMask) == kAsciiDataHintTag;
ricow@chromium.orgaa1b6162010-03-29 07:44:58 +0000319}
320
321
ager@chromium.org870a0b62008-11-04 11:43:05 +0000322bool StringShape::IsCons() {
323 return (type_ & kStringRepresentationMask) == kConsStringTag;
324}
325
326
ricow@chromium.org4668a2c2011-08-29 10:41:00 +0000327bool StringShape::IsSliced() {
328 return (type_ & kStringRepresentationMask) == kSlicedStringTag;
329}
330
331
332bool StringShape::IsIndirect() {
333 return (type_ & kIsIndirectStringMask) == kIsIndirectStringTag;
334}
335
336
ager@chromium.org870a0b62008-11-04 11:43:05 +0000337bool StringShape::IsExternal() {
338 return (type_ & kStringRepresentationMask) == kExternalStringTag;
339}
340
341
342bool StringShape::IsSequential() {
343 return (type_ & kStringRepresentationMask) == kSeqStringTag;
344}
345
346
347StringRepresentationTag StringShape::representation_tag() {
348 uint32_t tag = (type_ & kStringRepresentationMask);
349 return static_cast<StringRepresentationTag>(tag);
350}
351
352
ricow@chromium.orgddd545c2011-08-24 12:02:41 +0000353uint32_t StringShape::encoding_tag() {
354 return type_ & kStringEncodingMask;
355}
356
357
ager@chromium.org870a0b62008-11-04 11:43:05 +0000358uint32_t StringShape::full_representation_tag() {
359 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
360}
361
362
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000363STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
364 Internals::kFullStringRepresentationMask);
365
366
ager@chromium.org870a0b62008-11-04 11:43:05 +0000367bool StringShape::IsSequentialAscii() {
368 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
369}
370
371
372bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000373 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000374}
375
376
377bool StringShape::IsExternalAscii() {
378 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
379}
380
381
382bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000383 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000384}
385
386
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000387STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
388 Internals::kExternalTwoByteRepresentationTag);
389
390
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000391uc32 FlatStringReader::Get(int index) {
392 ASSERT(0 <= index && index <= length_);
393 if (is_ascii_) {
394 return static_cast<const byte*>(start_)[index];
395 } else {
396 return static_cast<const uc16*>(start_)[index];
397 }
398}
399
400
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000401bool Object::IsNumber() {
402 return IsSmi() || IsHeapNumber();
403}
404
405
406bool Object::IsByteArray() {
407 return Object::IsHeapObject()
408 && HeapObject::cast(this)->map()->instance_type() == BYTE_ARRAY_TYPE;
409}
410
411
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000412bool Object::IsFreeSpace() {
413 return Object::IsHeapObject()
414 && HeapObject::cast(this)->map()->instance_type() == FREE_SPACE_TYPE;
415}
416
417
418bool Object::IsFiller() {
419 if (!Object::IsHeapObject()) return false;
420 InstanceType instance_type = HeapObject::cast(this)->map()->instance_type();
421 return instance_type == FREE_SPACE_TYPE || instance_type == FILLER_TYPE;
422}
423
424
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000425bool Object::IsExternalPixelArray() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000426 return Object::IsHeapObject() &&
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000427 HeapObject::cast(this)->map()->instance_type() ==
428 EXTERNAL_PIXEL_ARRAY_TYPE;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000429}
430
431
ager@chromium.org3811b432009-10-28 14:53:37 +0000432bool Object::IsExternalArray() {
433 if (!Object::IsHeapObject())
434 return false;
435 InstanceType instance_type =
436 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000437 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
438 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000439}
440
441
442bool Object::IsExternalByteArray() {
443 return Object::IsHeapObject() &&
444 HeapObject::cast(this)->map()->instance_type() ==
445 EXTERNAL_BYTE_ARRAY_TYPE;
446}
447
448
449bool Object::IsExternalUnsignedByteArray() {
450 return Object::IsHeapObject() &&
451 HeapObject::cast(this)->map()->instance_type() ==
452 EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE;
453}
454
455
456bool Object::IsExternalShortArray() {
457 return Object::IsHeapObject() &&
458 HeapObject::cast(this)->map()->instance_type() ==
459 EXTERNAL_SHORT_ARRAY_TYPE;
460}
461
462
463bool Object::IsExternalUnsignedShortArray() {
464 return Object::IsHeapObject() &&
465 HeapObject::cast(this)->map()->instance_type() ==
466 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE;
467}
468
469
470bool Object::IsExternalIntArray() {
471 return Object::IsHeapObject() &&
472 HeapObject::cast(this)->map()->instance_type() ==
473 EXTERNAL_INT_ARRAY_TYPE;
474}
475
476
477bool Object::IsExternalUnsignedIntArray() {
478 return Object::IsHeapObject() &&
479 HeapObject::cast(this)->map()->instance_type() ==
480 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE;
481}
482
483
484bool Object::IsExternalFloatArray() {
485 return Object::IsHeapObject() &&
486 HeapObject::cast(this)->map()->instance_type() ==
487 EXTERNAL_FLOAT_ARRAY_TYPE;
488}
489
490
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000491bool Object::IsExternalDoubleArray() {
492 return Object::IsHeapObject() &&
493 HeapObject::cast(this)->map()->instance_type() ==
494 EXTERNAL_DOUBLE_ARRAY_TYPE;
495}
496
497
lrn@chromium.org303ada72010-10-27 09:33:13 +0000498bool MaybeObject::IsFailure() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000499 return HAS_FAILURE_TAG(this);
500}
501
502
lrn@chromium.org303ada72010-10-27 09:33:13 +0000503bool MaybeObject::IsRetryAfterGC() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000504 return HAS_FAILURE_TAG(this)
505 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
506}
507
508
lrn@chromium.org303ada72010-10-27 09:33:13 +0000509bool MaybeObject::IsOutOfMemory() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000510 return HAS_FAILURE_TAG(this)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000511 && Failure::cast(this)->IsOutOfMemoryException();
ager@chromium.org7c537e22008-10-16 08:43:32 +0000512}
513
514
lrn@chromium.org303ada72010-10-27 09:33:13 +0000515bool MaybeObject::IsException() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000516 return this == Failure::Exception();
517}
518
519
lrn@chromium.org303ada72010-10-27 09:33:13 +0000520bool MaybeObject::IsTheHole() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000521 return !IsFailure() && ToObjectUnchecked()->IsTheHole();
lrn@chromium.org303ada72010-10-27 09:33:13 +0000522}
523
524
525Failure* Failure::cast(MaybeObject* obj) {
526 ASSERT(HAS_FAILURE_TAG(obj));
527 return reinterpret_cast<Failure*>(obj);
528}
529
530
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000531bool Object::IsJSReceiver() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000532 STATIC_ASSERT(LAST_JS_RECEIVER_TYPE == LAST_TYPE);
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000533 return IsHeapObject() &&
534 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE;
535}
536
537
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000538bool Object::IsJSObject() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000539 STATIC_ASSERT(LAST_JS_OBJECT_TYPE == LAST_TYPE);
540 return IsHeapObject() &&
541 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000542}
543
544
545bool Object::IsJSProxy() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000546 if (!Object::IsHeapObject()) return false;
547 InstanceType type = HeapObject::cast(this)->map()->instance_type();
548 return FIRST_JS_PROXY_TYPE <= type && type <= LAST_JS_PROXY_TYPE;
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000549}
550
551
552bool Object::IsJSFunctionProxy() {
553 return Object::IsHeapObject() &&
554 HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_PROXY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000555}
556
557
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +0000558bool Object::IsJSWeakMap() {
559 return Object::IsJSObject() &&
560 HeapObject::cast(this)->map()->instance_type() == JS_WEAK_MAP_TYPE;
561}
562
563
ager@chromium.org32912102009-01-16 10:38:43 +0000564bool Object::IsJSContextExtensionObject() {
565 return IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000566 && (HeapObject::cast(this)->map()->instance_type() ==
567 JS_CONTEXT_EXTENSION_OBJECT_TYPE);
ager@chromium.org32912102009-01-16 10:38:43 +0000568}
569
570
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000571bool Object::IsMap() {
572 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000573 && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000574}
575
576
577bool Object::IsFixedArray() {
578 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000579 && HeapObject::cast(this)->map()->instance_type() == FIXED_ARRAY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000580}
581
582
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000583bool Object::IsFixedDoubleArray() {
584 return Object::IsHeapObject()
585 && HeapObject::cast(this)->map()->instance_type() ==
586 FIXED_DOUBLE_ARRAY_TYPE;
587}
588
589
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000590bool Object::IsDescriptorArray() {
591 return IsFixedArray();
592}
593
594
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000595bool Object::IsDeoptimizationInputData() {
596 // Must be a fixed array.
597 if (!IsFixedArray()) return false;
598
599 // There's no sure way to detect the difference between a fixed array and
600 // a deoptimization data array. Since this is used for asserts we can
601 // check that the length is zero or else the fixed size plus a multiple of
602 // the entry size.
603 int length = FixedArray::cast(this)->length();
604 if (length == 0) return true;
605
606 length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
607 return length >= 0 &&
608 length % DeoptimizationInputData::kDeoptEntrySize == 0;
609}
610
611
612bool Object::IsDeoptimizationOutputData() {
613 if (!IsFixedArray()) return false;
614 // There's actually no way to see the difference between a fixed array and
615 // a deoptimization data array. Since this is used for asserts we can check
616 // that the length is plausible though.
617 if (FixedArray::cast(this)->length() % 2 != 0) return false;
618 return true;
619}
620
621
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000622bool Object::IsContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000623 if (Object::IsHeapObject()) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000624 Map* map = HeapObject::cast(this)->map();
625 Heap* heap = map->GetHeap();
626 return (map == heap->function_context_map() ||
627 map == heap->catch_context_map() ||
628 map == heap->with_context_map() ||
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000629 map == heap->global_context_map() ||
630 map == heap->block_context_map());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000631 }
632 return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000633}
634
635
636bool Object::IsGlobalContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000637 return Object::IsHeapObject() &&
638 HeapObject::cast(this)->map() ==
639 HeapObject::cast(this)->GetHeap()->global_context_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000640}
641
642
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +0000643bool Object::IsSerializedScopeInfo() {
644 return Object::IsHeapObject() &&
645 HeapObject::cast(this)->map() ==
646 HeapObject::cast(this)->GetHeap()->serialized_scope_info_map();
647}
648
649
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000650bool Object::IsJSFunction() {
651 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000652 && HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000653}
654
655
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000656template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000657 return obj->IsJSFunction();
658}
659
660
661bool Object::IsCode() {
662 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000663 && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000664}
665
666
667bool Object::IsOddball() {
668 return Object::IsHeapObject()
669 && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE;
670}
671
672
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000673bool Object::IsJSGlobalPropertyCell() {
674 return Object::IsHeapObject()
675 && HeapObject::cast(this)->map()->instance_type()
676 == JS_GLOBAL_PROPERTY_CELL_TYPE;
677}
678
679
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000680bool Object::IsSharedFunctionInfo() {
681 return Object::IsHeapObject() &&
682 (HeapObject::cast(this)->map()->instance_type() ==
683 SHARED_FUNCTION_INFO_TYPE);
684}
685
686
687bool Object::IsJSValue() {
688 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000689 && HeapObject::cast(this)->map()->instance_type() == JS_VALUE_TYPE;
690}
691
692
693bool Object::IsJSMessageObject() {
694 return Object::IsHeapObject()
695 && (HeapObject::cast(this)->map()->instance_type() ==
696 JS_MESSAGE_OBJECT_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000697}
698
699
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000700bool Object::IsStringWrapper() {
701 return IsJSValue() && JSValue::cast(this)->value()->IsString();
702}
703
704
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000705bool Object::IsForeign() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000706 return Object::IsHeapObject()
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000707 && HeapObject::cast(this)->map()->instance_type() == FOREIGN_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000708}
709
710
711bool Object::IsBoolean() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000712 return IsOddball() &&
713 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000714}
715
716
717bool Object::IsJSArray() {
718 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000719 && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000720}
721
722
ager@chromium.org236ad962008-09-25 09:45:57 +0000723bool Object::IsJSRegExp() {
724 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000725 && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
ager@chromium.org236ad962008-09-25 09:45:57 +0000726}
727
728
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000729template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000730 return obj->IsJSArray();
731}
732
733
734bool Object::IsHashTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000735 return Object::IsHeapObject() &&
736 HeapObject::cast(this)->map() ==
737 HeapObject::cast(this)->GetHeap()->hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000738}
739
740
741bool Object::IsDictionary() {
whesse@chromium.org7b260152011-06-20 15:33:18 +0000742 return IsHashTable() &&
743 this != HeapObject::cast(this)->GetHeap()->symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000744}
745
746
747bool Object::IsSymbolTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000748 return IsHashTable() && this ==
749 HeapObject::cast(this)->GetHeap()->raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000750}
751
752
ager@chromium.orgac091b72010-05-05 07:34:42 +0000753bool Object::IsJSFunctionResultCache() {
754 if (!IsFixedArray()) return false;
755 FixedArray* self = FixedArray::cast(this);
756 int length = self->length();
757 if (length < JSFunctionResultCache::kEntriesIndex) return false;
758 if ((length - JSFunctionResultCache::kEntriesIndex)
759 % JSFunctionResultCache::kEntrySize != 0) {
760 return false;
761 }
762#ifdef DEBUG
763 reinterpret_cast<JSFunctionResultCache*>(this)->JSFunctionResultCacheVerify();
764#endif
765 return true;
766}
767
768
ricow@chromium.org65fae842010-08-25 15:26:24 +0000769bool Object::IsNormalizedMapCache() {
770 if (!IsFixedArray()) return false;
771 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
772 return false;
773 }
774#ifdef DEBUG
775 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
776#endif
777 return true;
778}
779
780
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000781bool Object::IsCompilationCacheTable() {
782 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000783}
784
785
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000786bool Object::IsCodeCacheHashTable() {
787 return IsHashTable();
788}
789
790
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000791bool Object::IsPolymorphicCodeCacheHashTable() {
792 return IsHashTable();
793}
794
795
ager@chromium.org236ad962008-09-25 09:45:57 +0000796bool Object::IsMapCache() {
797 return IsHashTable();
798}
799
800
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000801bool Object::IsPrimitive() {
802 return IsOddball() || IsNumber() || IsString();
803}
804
805
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000806bool Object::IsJSGlobalProxy() {
807 bool result = IsHeapObject() &&
808 (HeapObject::cast(this)->map()->instance_type() ==
809 JS_GLOBAL_PROXY_TYPE);
810 ASSERT(!result || IsAccessCheckNeeded());
811 return result;
812}
813
814
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000815bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000816 if (!IsHeapObject()) return false;
817
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000818 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000819 return type == JS_GLOBAL_OBJECT_TYPE ||
820 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000821}
822
823
824bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000825 return IsHeapObject() &&
826 (HeapObject::cast(this)->map()->instance_type() ==
827 JS_GLOBAL_OBJECT_TYPE);
828}
829
830
831bool Object::IsJSBuiltinsObject() {
832 return IsHeapObject() &&
833 (HeapObject::cast(this)->map()->instance_type() ==
834 JS_BUILTINS_OBJECT_TYPE);
835}
836
837
838bool Object::IsUndetectableObject() {
839 return IsHeapObject()
840 && HeapObject::cast(this)->map()->is_undetectable();
841}
842
843
844bool Object::IsAccessCheckNeeded() {
845 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000846 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000847}
848
849
850bool Object::IsStruct() {
851 if (!IsHeapObject()) return false;
852 switch (HeapObject::cast(this)->map()->instance_type()) {
853#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
854 STRUCT_LIST(MAKE_STRUCT_CASE)
855#undef MAKE_STRUCT_CASE
856 default: return false;
857 }
858}
859
860
861#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
862 bool Object::Is##Name() { \
863 return Object::IsHeapObject() \
864 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
865 }
866 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
867#undef MAKE_STRUCT_PREDICATE
868
869
870bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000871 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000872}
873
874
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000875bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000876 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
877}
878
879
880bool Object::IsTheHole() {
881 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000882}
883
884
885bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000886 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000887}
888
889
890bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000891 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000892}
893
894
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000895bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000896 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000897}
898
899
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000900double Object::Number() {
901 ASSERT(IsNumber());
902 return IsSmi()
903 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
904 : reinterpret_cast<HeapNumber*>(this)->value();
905}
906
907
lrn@chromium.org303ada72010-10-27 09:33:13 +0000908MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000909 if (IsSmi()) return this;
910 if (IsHeapNumber()) {
911 double value = HeapNumber::cast(this)->value();
912 int int_value = FastD2I(value);
913 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
914 return Smi::FromInt(int_value);
915 }
916 }
917 return Failure::Exception();
918}
919
920
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000921bool Object::HasSpecificClassOf(String* name) {
922 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
923}
924
925
lrn@chromium.org303ada72010-10-27 09:33:13 +0000926MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000927 // GetElement can trigger a getter which can cause allocation.
928 // This was not always the case. This ASSERT is here to catch
929 // leftover incorrect uses.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000930 ASSERT(HEAP->IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000931 return GetElementWithReceiver(this, index);
932}
933
934
lrn@chromium.org303ada72010-10-27 09:33:13 +0000935Object* Object::GetElementNoExceptionThrown(uint32_t index) {
936 MaybeObject* maybe = GetElementWithReceiver(this, index);
937 ASSERT(!maybe->IsFailure());
938 Object* result = NULL; // Initialization to please compiler.
939 maybe->ToObject(&result);
940 return result;
941}
942
943
944MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000945 PropertyAttributes attributes;
946 return GetPropertyWithReceiver(this, key, &attributes);
947}
948
949
lrn@chromium.org303ada72010-10-27 09:33:13 +0000950MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000951 return GetPropertyWithReceiver(this, key, attributes);
952}
953
954
955#define FIELD_ADDR(p, offset) \
956 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
957
958#define READ_FIELD(p, offset) \
959 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
960
961#define WRITE_FIELD(p, offset, value) \
962 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
963
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000964#define WRITE_BARRIER(heap, object, offset, value) \
965 heap->incremental_marking()->RecordWrite( \
966 object, HeapObject::RawField(object, offset), value); \
967 if (heap->InNewSpace(value)) { \
968 heap->RecordWrite(object->address(), offset); \
969 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000970
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +0000971#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, value, mode) \
972 if (mode == UPDATE_WRITE_BARRIER) { \
973 heap->incremental_marking()->RecordWrite( \
974 object, HeapObject::RawField(object, offset), value); \
975 if (heap->InNewSpace(value)) { \
976 heap->RecordWrite(object->address(), offset); \
977 } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000978 }
979
lrn@chromium.org7516f052011-03-30 08:52:27 +0000980#ifndef V8_TARGET_ARCH_MIPS
981 #define READ_DOUBLE_FIELD(p, offset) \
982 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
983#else // V8_TARGET_ARCH_MIPS
984 // Prevent gcc from using load-double (mips ldc1) on (possibly)
985 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000986 static inline double read_double_field(void* p, int offset) {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000987 union conversion {
988 double d;
989 uint32_t u[2];
990 } c;
991 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
992 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
993 return c.d;
994 }
995 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
996#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000997
lrn@chromium.org7516f052011-03-30 08:52:27 +0000998#ifndef V8_TARGET_ARCH_MIPS
999 #define WRITE_DOUBLE_FIELD(p, offset, value) \
1000 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
1001#else // V8_TARGET_ARCH_MIPS
1002 // Prevent gcc from using store-double (mips sdc1) on (possibly)
1003 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001004 static inline void write_double_field(void* p, int offset,
lrn@chromium.org7516f052011-03-30 08:52:27 +00001005 double value) {
1006 union conversion {
1007 double d;
1008 uint32_t u[2];
1009 } c;
1010 c.d = value;
1011 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
1012 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
1013 }
1014 #define WRITE_DOUBLE_FIELD(p, offset, value) \
1015 write_double_field(p, offset, value)
1016#endif // V8_TARGET_ARCH_MIPS
1017
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001018
1019#define READ_INT_FIELD(p, offset) \
1020 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
1021
1022#define WRITE_INT_FIELD(p, offset, value) \
1023 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
1024
ager@chromium.org3e875802009-06-29 08:26:34 +00001025#define READ_INTPTR_FIELD(p, offset) \
1026 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
1027
1028#define WRITE_INTPTR_FIELD(p, offset, value) \
1029 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
1030
ager@chromium.org7c537e22008-10-16 08:43:32 +00001031#define READ_UINT32_FIELD(p, offset) \
1032 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
1033
1034#define WRITE_UINT32_FIELD(p, offset, value) \
1035 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
1036
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001037#define READ_SHORT_FIELD(p, offset) \
1038 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
1039
1040#define WRITE_SHORT_FIELD(p, offset, value) \
1041 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
1042
1043#define READ_BYTE_FIELD(p, offset) \
1044 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
1045
1046#define WRITE_BYTE_FIELD(p, offset, value) \
1047 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
1048
1049
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +00001050Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
1051 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001052}
1053
1054
1055int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +00001056 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001057}
1058
1059
1060Smi* Smi::FromInt(int value) {
1061 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001062 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +00001063 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001064 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +00001065 return reinterpret_cast<Smi*>(tagged_value);
1066}
1067
1068
1069Smi* Smi::FromIntptr(intptr_t value) {
1070 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001071 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
1072 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001073}
1074
1075
1076Failure::Type Failure::type() const {
1077 return static_cast<Type>(value() & kFailureTypeTagMask);
1078}
1079
1080
1081bool Failure::IsInternalError() const {
1082 return type() == INTERNAL_ERROR;
1083}
1084
1085
1086bool Failure::IsOutOfMemoryException() const {
1087 return type() == OUT_OF_MEMORY_EXCEPTION;
1088}
1089
1090
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001091AllocationSpace Failure::allocation_space() const {
1092 ASSERT_EQ(RETRY_AFTER_GC, type());
1093 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
1094 & kSpaceTagMask);
1095}
1096
1097
1098Failure* Failure::InternalError() {
1099 return Construct(INTERNAL_ERROR);
1100}
1101
1102
1103Failure* Failure::Exception() {
1104 return Construct(EXCEPTION);
1105}
1106
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00001107
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001108Failure* Failure::OutOfMemoryException() {
1109 return Construct(OUT_OF_MEMORY_EXCEPTION);
1110}
1111
1112
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001113intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001114 return static_cast<intptr_t>(
1115 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001116}
1117
1118
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001119Failure* Failure::RetryAfterGC() {
1120 return RetryAfterGC(NEW_SPACE);
1121}
1122
1123
1124Failure* Failure::RetryAfterGC(AllocationSpace space) {
1125 ASSERT((space & ~kSpaceTagMask) == 0);
1126 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001127}
1128
1129
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001130Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001131 uintptr_t info =
1132 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001133 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001134 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001135}
1136
1137
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001138bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001139#ifdef DEBUG
1140 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1141#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001142
1143#ifdef V8_TARGET_ARCH_X64
1144 // To be representable as a long smi, the value must be a 32-bit integer.
1145 bool result = (value == static_cast<int32_t>(value));
1146#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001147 // To be representable as an tagged small integer, the two
1148 // most-significant bits of 'value' must be either 00 or 11 due to
1149 // sign-extension. To check this we add 01 to the two
1150 // most-significant bits, and check if the most-significant bit is 0
1151 //
1152 // CAUTION: The original code below:
1153 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1154 // may lead to incorrect results according to the C language spec, and
1155 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1156 // compiler may produce undefined results in case of signed integer
1157 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001158 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001159#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001160 ASSERT(result == in_range);
1161 return result;
1162}
1163
1164
kasper.lund7276f142008-07-30 08:49:36 +00001165MapWord MapWord::FromMap(Map* map) {
1166 return MapWord(reinterpret_cast<uintptr_t>(map));
1167}
1168
1169
1170Map* MapWord::ToMap() {
1171 return reinterpret_cast<Map*>(value_);
1172}
1173
1174
1175bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001176 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001177}
1178
1179
1180MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001181 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1182 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001183}
1184
1185
1186HeapObject* MapWord::ToForwardingAddress() {
1187 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001188 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001189}
1190
1191
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001192#ifdef DEBUG
1193void HeapObject::VerifyObjectField(int offset) {
1194 VerifyPointer(READ_FIELD(this, offset));
1195}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001196
1197void HeapObject::VerifySmiField(int offset) {
1198 ASSERT(READ_FIELD(this, offset)->IsSmi());
1199}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001200#endif
1201
1202
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001203Heap* HeapObject::GetHeap() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001204 Heap* heap =
1205 MemoryChunk::FromAddress(reinterpret_cast<Address>(this))->heap();
1206 ASSERT(heap != NULL);
1207 ASSERT(heap->isolate() == Isolate::Current());
1208 return heap;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001209}
1210
1211
1212Isolate* HeapObject::GetIsolate() {
1213 return GetHeap()->isolate();
1214}
1215
1216
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001217Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001218 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001219}
1220
1221
1222void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001223 set_map_word(MapWord::FromMap(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001224 if (value != NULL) {
1225 // TODO(1600) We are passing NULL as a slot because maps can never be on
1226 // evacuation candidate.
1227 value->GetHeap()->incremental_marking()->RecordWrite(this, NULL, value);
1228 }
1229}
1230
1231
1232// Unsafe accessor omitting write barrier.
1233void HeapObject::set_map_unsafe(Map* value) {
1234 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001235}
1236
1237
kasper.lund7276f142008-07-30 08:49:36 +00001238MapWord HeapObject::map_word() {
1239 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1240}
1241
1242
1243void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001244 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001245 // here.
1246 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1247}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001248
1249
1250HeapObject* HeapObject::FromAddress(Address address) {
1251 ASSERT_TAG_ALIGNED(address);
1252 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1253}
1254
1255
1256Address HeapObject::address() {
1257 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1258}
1259
1260
1261int HeapObject::Size() {
1262 return SizeFromMap(map());
1263}
1264
1265
1266void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1267 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1268 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1269}
1270
1271
1272void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1273 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1274}
1275
1276
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001277double HeapNumber::value() {
1278 return READ_DOUBLE_FIELD(this, kValueOffset);
1279}
1280
1281
1282void HeapNumber::set_value(double value) {
1283 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1284}
1285
1286
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001287int HeapNumber::get_exponent() {
1288 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1289 kExponentShift) - kExponentBias;
1290}
1291
1292
1293int HeapNumber::get_sign() {
1294 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1295}
1296
1297
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001298ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001299
1300
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001301FixedArrayBase* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001302 Object* array = READ_FIELD(this, kElementsOffset);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001303 ASSERT(array->HasValidElements());
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001304 return static_cast<FixedArrayBase*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001305}
1306
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001307void JSObject::ValidateSmiOnlyElements() {
1308#if DEBUG
1309 if (FLAG_smi_only_arrays &&
1310 map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) {
1311 Heap* heap = GetHeap();
1312 // Don't use elements, since integrity checks will fail if there
1313 // are filler pointers in the array.
1314 FixedArray* fixed_array =
1315 reinterpret_cast<FixedArray*>(READ_FIELD(this, kElementsOffset));
1316 Map* map = fixed_array->map();
1317 // Arrays that have been shifted in place can't be verified.
1318 if (map != heap->raw_unchecked_one_pointer_filler_map() &&
1319 map != heap->raw_unchecked_two_pointer_filler_map() &&
1320 map != heap->free_space_map()) {
1321 for (int i = 0; i < fixed_array->length(); i++) {
1322 Object* current = fixed_array->get(i);
1323 ASSERT(current->IsSmi() || current == heap->the_hole_value());
1324 }
1325 }
1326 }
1327#endif
1328}
1329
1330
1331MaybeObject* JSObject::EnsureCanContainNonSmiElements() {
1332#if DEBUG
1333 ValidateSmiOnlyElements();
1334#endif
1335 if (FLAG_smi_only_arrays &&
1336 (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS)) {
1337 Object* obj;
1338 MaybeObject* maybe_obj = GetElementsTransitionMap(FAST_ELEMENTS);
1339 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1340 set_map(Map::cast(obj));
1341 }
1342 return this;
1343}
1344
1345
1346MaybeObject* JSObject::EnsureCanContainElements(Object** objects,
1347 uint32_t count) {
1348 if (FLAG_smi_only_arrays &&
1349 map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) {
1350 for (uint32_t i = 0; i < count; ++i) {
1351 Object* current = *objects++;
1352 if (!current->IsSmi() && current != GetHeap()->the_hole_value()) {
1353 return EnsureCanContainNonSmiElements();
1354 }
1355 }
1356 }
1357 return this;
1358}
1359
1360
1361MaybeObject* JSObject::EnsureCanContainElements(FixedArray* elements) {
1362 if (FLAG_smi_only_arrays) {
1363 Object** objects = reinterpret_cast<Object**>(
1364 FIELD_ADDR(elements, elements->OffsetOfElementAt(0)));
1365 return EnsureCanContainElements(objects, elements->length());
1366 } else {
1367 return this;
1368 }
1369}
1370
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001371
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001372void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001373 ASSERT((map()->has_fast_elements() ||
1374 map()->has_fast_smi_only_elements()) ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001375 (value->map() == GetHeap()->fixed_array_map() ||
1376 value->map() == GetHeap()->fixed_cow_array_map()));
lrn@chromium.orgd4e9e222011-08-03 12:01:58 +00001377 ASSERT(map()->has_fast_double_elements() ==
1378 value->IsFixedDoubleArray());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001379 ASSERT(value->HasValidElements());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001380#ifdef DEBUG
1381 ValidateSmiOnlyElements();
1382#endif
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001383 WRITE_FIELD(this, kElementsOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001384 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001385}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001386
1387
1388void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001389 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1390 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001391}
1392
1393
1394void JSObject::initialize_elements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001395 ASSERT(map()->has_fast_elements() || map()->has_fast_smi_only_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001396 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1397 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001398}
1399
1400
lrn@chromium.org303ada72010-10-27 09:33:13 +00001401MaybeObject* JSObject::ResetElements() {
1402 Object* obj;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001403 ElementsKind elements_kind = FLAG_smi_only_arrays
1404 ? FAST_SMI_ONLY_ELEMENTS
1405 : FAST_ELEMENTS;
1406 MaybeObject* maybe_obj = GetElementsTransitionMap(elements_kind);
1407 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001408 set_map(Map::cast(obj));
1409 initialize_elements();
1410 return this;
1411}
1412
1413
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001414ACCESSORS(Oddball, to_string, String, kToStringOffset)
1415ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1416
1417
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001418byte Oddball::kind() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001419 return Smi::cast(READ_FIELD(this, kKindOffset))->value();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001420}
1421
1422
1423void Oddball::set_kind(byte value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001424 WRITE_FIELD(this, kKindOffset, Smi::FromInt(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001425}
1426
1427
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001428Object* JSGlobalPropertyCell::value() {
1429 return READ_FIELD(this, kValueOffset);
1430}
1431
1432
1433void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1434 // The write barrier is not used for global property cells.
1435 ASSERT(!val->IsJSGlobalPropertyCell());
1436 WRITE_FIELD(this, kValueOffset, val);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001437 GetHeap()->incremental_marking()->RecordWrite(
1438 this, HeapObject::RawField(this, kValueOffset), val);
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001439}
1440
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001441
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001442int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001443 InstanceType type = map()->instance_type();
1444 // Check for the most common kind of JavaScript object before
1445 // falling into the generic switch. This speeds up the internal
1446 // field operations considerably on average.
1447 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1448 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001449 case JS_GLOBAL_PROXY_TYPE:
1450 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001451 case JS_GLOBAL_OBJECT_TYPE:
1452 return JSGlobalObject::kSize;
1453 case JS_BUILTINS_OBJECT_TYPE:
1454 return JSBuiltinsObject::kSize;
1455 case JS_FUNCTION_TYPE:
1456 return JSFunction::kSize;
1457 case JS_VALUE_TYPE:
1458 return JSValue::kSize;
1459 case JS_ARRAY_TYPE:
1460 return JSValue::kSize;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001461 case JS_WEAK_MAP_TYPE:
1462 return JSWeakMap::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001463 case JS_REGEXP_TYPE:
1464 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001465 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001466 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001467 case JS_MESSAGE_OBJECT_TYPE:
1468 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001469 default:
1470 UNREACHABLE();
1471 return 0;
1472 }
1473}
1474
1475
1476int JSObject::GetInternalFieldCount() {
1477 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001478 // Make sure to adjust for the number of in-object properties. These
1479 // properties do contribute to the size, but are not internal fields.
1480 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1481 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001482}
1483
1484
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001485int JSObject::GetInternalFieldOffset(int index) {
1486 ASSERT(index < GetInternalFieldCount() && index >= 0);
1487 return GetHeaderSize() + (kPointerSize * index);
1488}
1489
1490
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001491Object* JSObject::GetInternalField(int index) {
1492 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001493 // Internal objects do follow immediately after the header, whereas in-object
1494 // properties are at the end of the object. Therefore there is no need
1495 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001496 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1497}
1498
1499
1500void JSObject::SetInternalField(int index, Object* value) {
1501 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001502 // Internal objects do follow immediately after the header, whereas in-object
1503 // properties are at the end of the object. Therefore there is no need
1504 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001505 int offset = GetHeaderSize() + (kPointerSize * index);
1506 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001507 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001508}
1509
1510
ager@chromium.org7c537e22008-10-16 08:43:32 +00001511// Access fast-case object properties at index. The use of these routines
1512// is needed to correctly distinguish between properties stored in-object and
1513// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001514Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001515 // Adjust for the number of properties stored in the object.
1516 index -= map()->inobject_properties();
1517 if (index < 0) {
1518 int offset = map()->instance_size() + (index * kPointerSize);
1519 return READ_FIELD(this, offset);
1520 } else {
1521 ASSERT(index < properties()->length());
1522 return properties()->get(index);
1523 }
1524}
1525
1526
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001527Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001528 // Adjust for the number of properties stored in the object.
1529 index -= map()->inobject_properties();
1530 if (index < 0) {
1531 int offset = map()->instance_size() + (index * kPointerSize);
1532 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001533 WRITE_BARRIER(GetHeap(), this, offset, value);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001534 } else {
1535 ASSERT(index < properties()->length());
1536 properties()->set(index, value);
1537 }
1538 return value;
1539}
1540
1541
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001542int JSObject::GetInObjectPropertyOffset(int index) {
1543 // Adjust for the number of properties stored in the object.
1544 index -= map()->inobject_properties();
1545 ASSERT(index < 0);
1546 return map()->instance_size() + (index * kPointerSize);
1547}
1548
1549
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001550Object* JSObject::InObjectPropertyAt(int index) {
1551 // Adjust for the number of properties stored in the object.
1552 index -= map()->inobject_properties();
1553 ASSERT(index < 0);
1554 int offset = map()->instance_size() + (index * kPointerSize);
1555 return READ_FIELD(this, offset);
1556}
1557
1558
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001559Object* JSObject::InObjectPropertyAtPut(int index,
1560 Object* value,
1561 WriteBarrierMode mode) {
1562 // Adjust for the number of properties stored in the object.
1563 index -= map()->inobject_properties();
1564 ASSERT(index < 0);
1565 int offset = map()->instance_size() + (index * kPointerSize);
1566 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001567 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001568 return value;
1569}
1570
1571
1572
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001573void JSObject::InitializeBody(Map* map,
1574 Object* pre_allocated_value,
1575 Object* filler_value) {
1576 ASSERT(!filler_value->IsHeapObject() ||
1577 !GetHeap()->InNewSpace(filler_value));
1578 ASSERT(!pre_allocated_value->IsHeapObject() ||
1579 !GetHeap()->InNewSpace(pre_allocated_value));
1580 int size = map->instance_size();
1581 int offset = kHeaderSize;
1582 if (filler_value != pre_allocated_value) {
1583 int pre_allocated = map->pre_allocated_property_fields();
1584 ASSERT(pre_allocated * kPointerSize + kHeaderSize <= size);
1585 for (int i = 0; i < pre_allocated; i++) {
1586 WRITE_FIELD(this, offset, pre_allocated_value);
1587 offset += kPointerSize;
1588 }
1589 }
1590 while (offset < size) {
1591 WRITE_FIELD(this, offset, filler_value);
1592 offset += kPointerSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001593 }
1594}
1595
1596
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001597bool JSObject::HasFastProperties() {
1598 return !properties()->IsDictionary();
1599}
1600
1601
1602int JSObject::MaxFastProperties() {
1603 // Allow extra fast properties if the object has more than
1604 // kMaxFastProperties in-object properties. When this is the case,
1605 // it is very unlikely that the object is being used as a dictionary
1606 // and there is a good chance that allowing more map transitions
1607 // will be worth it.
1608 return Max(map()->inobject_properties(), kMaxFastProperties);
1609}
1610
1611
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001612void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001613 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001614 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001615 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001616 }
1617}
1618
1619
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001620bool Object::ToArrayIndex(uint32_t* index) {
1621 if (IsSmi()) {
1622 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001623 if (value < 0) return false;
1624 *index = value;
1625 return true;
1626 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001627 if (IsHeapNumber()) {
1628 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001629 uint32_t uint_value = static_cast<uint32_t>(value);
1630 if (value == static_cast<double>(uint_value)) {
1631 *index = uint_value;
1632 return true;
1633 }
1634 }
1635 return false;
1636}
1637
1638
1639bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1640 if (!this->IsJSValue()) return false;
1641
1642 JSValue* js_value = JSValue::cast(this);
1643 if (!js_value->value()->IsString()) return false;
1644
1645 String* str = String::cast(js_value->value());
1646 if (index >= (uint32_t)str->length()) return false;
1647
1648 return true;
1649}
1650
1651
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001652FixedArrayBase* FixedArrayBase::cast(Object* object) {
1653 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1654 return reinterpret_cast<FixedArrayBase*>(object);
1655}
1656
1657
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001658Object* FixedArray::get(int index) {
1659 ASSERT(index >= 0 && index < this->length());
1660 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1661}
1662
1663
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001664void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001665 ASSERT(map() != HEAP->fixed_cow_array_map());
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001666 ASSERT(index >= 0 && index < this->length());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001667 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1668 int offset = kHeaderSize + index * kPointerSize;
1669 WRITE_FIELD(this, offset, value);
1670}
1671
1672
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001673void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001674 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001675 ASSERT(index >= 0 && index < this->length());
1676 int offset = kHeaderSize + index * kPointerSize;
1677 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001678 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001679}
1680
1681
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001682inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1683 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1684}
1685
1686
1687inline double FixedDoubleArray::hole_nan_as_double() {
1688 return BitCast<double, uint64_t>(kHoleNanInt64);
1689}
1690
1691
1692inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1693 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1694 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1695 return OS::nan_value();
1696}
1697
1698
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001699double FixedDoubleArray::get_scalar(int index) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001700 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1701 map() != HEAP->fixed_array_map());
1702 ASSERT(index >= 0 && index < this->length());
1703 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1704 ASSERT(!is_the_hole_nan(result));
1705 return result;
1706}
1707
1708
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001709MaybeObject* FixedDoubleArray::get(int index) {
1710 if (is_the_hole(index)) {
1711 return GetHeap()->the_hole_value();
1712 } else {
1713 return GetHeap()->NumberFromDouble(get_scalar(index));
1714 }
1715}
1716
1717
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001718void FixedDoubleArray::set(int index, double value) {
1719 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1720 map() != HEAP->fixed_array_map());
1721 int offset = kHeaderSize + index * kDoubleSize;
1722 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1723 WRITE_DOUBLE_FIELD(this, offset, value);
1724}
1725
1726
1727void FixedDoubleArray::set_the_hole(int index) {
1728 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1729 map() != HEAP->fixed_array_map());
1730 int offset = kHeaderSize + index * kDoubleSize;
1731 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1732}
1733
1734
1735bool FixedDoubleArray::is_the_hole(int index) {
1736 int offset = kHeaderSize + index * kDoubleSize;
1737 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1738}
1739
1740
1741void FixedDoubleArray::Initialize(FixedDoubleArray* from) {
1742 int old_length = from->length();
1743 ASSERT(old_length < length());
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001744 if (old_length * kDoubleSize >= OS::kMinComplexMemCopy) {
1745 OS::MemCopy(FIELD_ADDR(this, kHeaderSize),
1746 FIELD_ADDR(from, kHeaderSize),
1747 old_length * kDoubleSize);
1748 } else {
1749 for (int i = 0; i < old_length; ++i) {
1750 set(i, from->get_scalar(i));
1751 }
1752 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001753 int offset = kHeaderSize + old_length * kDoubleSize;
1754 for (int current = from->length(); current < length(); ++current) {
1755 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1756 offset += kDoubleSize;
1757 }
1758}
1759
1760
1761void FixedDoubleArray::Initialize(FixedArray* from) {
1762 int old_length = from->length();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001763 ASSERT(old_length <= length());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001764 for (int i = 0; i < old_length; i++) {
1765 Object* hole_or_object = from->get(i);
1766 if (hole_or_object->IsTheHole()) {
1767 set_the_hole(i);
1768 } else {
1769 set(i, hole_or_object->Number());
1770 }
1771 }
1772 int offset = kHeaderSize + old_length * kDoubleSize;
1773 for (int current = from->length(); current < length(); ++current) {
1774 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1775 offset += kDoubleSize;
1776 }
1777}
1778
1779
1780void FixedDoubleArray::Initialize(NumberDictionary* from) {
1781 int offset = kHeaderSize;
1782 for (int current = 0; current < length(); ++current) {
1783 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1784 offset += kDoubleSize;
1785 }
1786 for (int i = 0; i < from->Capacity(); i++) {
1787 Object* key = from->KeyAt(i);
1788 if (key->IsNumber()) {
1789 uint32_t entry = static_cast<uint32_t>(key->Number());
1790 set(entry, from->ValueAt(i)->Number());
1791 }
1792 }
1793}
1794
1795
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001796WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001797 Heap* heap = GetHeap();
1798 if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
1799 if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001800 return UPDATE_WRITE_BARRIER;
1801}
1802
1803
1804void FixedArray::set(int index,
1805 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001806 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001807 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001808 ASSERT(index >= 0 && index < this->length());
1809 int offset = kHeaderSize + index * kPointerSize;
1810 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001811 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001812}
1813
1814
1815void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001816 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001817 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001818 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001819 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001820 array->GetHeap()->incremental_marking()->RecordWrite(
1821 array,
1822 HeapObject::RawField(array, kHeaderSize + index * kPointerSize),
1823 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001824}
1825
1826
1827void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001828 ASSERT(map() != HEAP->fixed_cow_array_map());
1829 set_undefined(GetHeap(), index);
1830}
1831
1832
1833void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001834 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001835 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001836 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001837 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001838}
1839
1840
ager@chromium.org236ad962008-09-25 09:45:57 +00001841void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001842 set_null(GetHeap(), index);
1843}
1844
1845
1846void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001847 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001848 ASSERT(!heap->InNewSpace(heap->null_value()));
1849 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001850}
1851
1852
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001853void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001854 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001855 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001856 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1857 WRITE_FIELD(this,
1858 kHeaderSize + index * kPointerSize,
1859 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001860}
1861
1862
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001863void FixedArray::set_unchecked(int index, Smi* value) {
1864 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1865 int offset = kHeaderSize + index * kPointerSize;
1866 WRITE_FIELD(this, offset, value);
1867}
1868
1869
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001870void FixedArray::set_unchecked(Heap* heap,
1871 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001872 Object* value,
1873 WriteBarrierMode mode) {
1874 int offset = kHeaderSize + index * kPointerSize;
1875 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001876 CONDITIONAL_WRITE_BARRIER(heap, this, offset, value, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001877}
1878
1879
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001880void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001881 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001882 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1883 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001884}
1885
1886
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001887Object** FixedArray::data_start() {
1888 return HeapObject::RawField(this, kHeaderSize);
1889}
1890
1891
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001892bool DescriptorArray::IsEmpty() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00001893 ASSERT(this->IsSmi() ||
1894 this->length() > kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001895 this == HEAP->empty_descriptor_array());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001896 return this->IsSmi() || length() <= kFirstIndex;
1897}
1898
1899
1900int DescriptorArray::bit_field3_storage() {
1901 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1902 return Smi::cast(storage)->value();
1903}
1904
1905void DescriptorArray::set_bit_field3_storage(int value) {
1906 ASSERT(!IsEmpty());
1907 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001908}
1909
1910
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001911void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1912 Object* tmp = array->get(first);
1913 fast_set(array, first, array->get(second));
1914 fast_set(array, second, tmp);
1915}
1916
1917
1918int DescriptorArray::Search(String* name) {
1919 SLOW_ASSERT(IsSortedNoDuplicates());
1920
1921 // Check for empty descriptor array.
1922 int nof = number_of_descriptors();
1923 if (nof == 0) return kNotFound;
1924
1925 // Fast case: do linear search for small arrays.
1926 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001927 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001928 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001929 }
1930
1931 // Slow case: perform binary search.
1932 return BinarySearch(name, 0, nof - 1);
1933}
1934
1935
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001936int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001937 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001938 if (number == DescriptorLookupCache::kAbsent) {
1939 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001940 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001941 }
1942 return number;
1943}
1944
1945
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001946String* DescriptorArray::GetKey(int descriptor_number) {
1947 ASSERT(descriptor_number < number_of_descriptors());
1948 return String::cast(get(ToKeyIndex(descriptor_number)));
1949}
1950
1951
1952Object* DescriptorArray::GetValue(int descriptor_number) {
1953 ASSERT(descriptor_number < number_of_descriptors());
1954 return GetContentArray()->get(ToValueIndex(descriptor_number));
1955}
1956
1957
1958Smi* DescriptorArray::GetDetails(int descriptor_number) {
1959 ASSERT(descriptor_number < number_of_descriptors());
1960 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1961}
1962
1963
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001964PropertyType DescriptorArray::GetType(int descriptor_number) {
1965 ASSERT(descriptor_number < number_of_descriptors());
1966 return PropertyDetails(GetDetails(descriptor_number)).type();
1967}
1968
1969
1970int DescriptorArray::GetFieldIndex(int descriptor_number) {
1971 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1972}
1973
1974
1975JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1976 return JSFunction::cast(GetValue(descriptor_number));
1977}
1978
1979
1980Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1981 ASSERT(GetType(descriptor_number) == CALLBACKS);
1982 return GetValue(descriptor_number);
1983}
1984
1985
1986AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1987 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001988 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
1989 return reinterpret_cast<AccessorDescriptor*>(p->address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001990}
1991
1992
1993bool DescriptorArray::IsProperty(int descriptor_number) {
1994 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1995}
1996
1997
1998bool DescriptorArray::IsTransition(int descriptor_number) {
1999 PropertyType t = GetType(descriptor_number);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00002000 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION ||
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002001 t == ELEMENTS_TRANSITION;
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002002}
2003
2004
2005bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
2006 return GetType(descriptor_number) == NULL_DESCRIPTOR;
2007}
2008
2009
2010bool DescriptorArray::IsDontEnum(int descriptor_number) {
2011 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
2012}
2013
2014
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002015void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
2016 desc->Init(GetKey(descriptor_number),
2017 GetValue(descriptor_number),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002018 PropertyDetails(GetDetails(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002019}
2020
2021
2022void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
2023 // Range check.
2024 ASSERT(descriptor_number < number_of_descriptors());
2025
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00002026 // Make sure none of the elements in desc are in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002027 ASSERT(!HEAP->InNewSpace(desc->GetKey()));
2028 ASSERT(!HEAP->InNewSpace(desc->GetValue()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002029
2030 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
2031 FixedArray* content_array = GetContentArray();
2032 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
2033 fast_set(content_array, ToDetailsIndex(descriptor_number),
2034 desc->GetDetails().AsSmi());
2035}
2036
2037
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002038void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
2039 Descriptor desc;
2040 src->Get(src_index, &desc);
2041 Set(index, &desc);
2042}
2043
2044
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002045void DescriptorArray::Swap(int first, int second) {
2046 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
2047 FixedArray* content_array = GetContentArray();
2048 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
2049 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
2050}
2051
2052
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002053template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00002054int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2055 const int kMinCapacity = 32;
2056 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2057 if (capacity < kMinCapacity) {
2058 capacity = kMinCapacity; // Guarantee min capacity.
2059 }
2060 return capacity;
2061}
2062
2063
2064template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002065int HashTable<Shape, Key>::FindEntry(Key key) {
2066 return FindEntry(GetIsolate(), key);
2067}
2068
2069
2070// Find entry for key otherwise return kNotFound.
2071template<typename Shape, typename Key>
2072int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2073 uint32_t capacity = Capacity();
2074 uint32_t entry = FirstProbe(Shape::Hash(key), capacity);
2075 uint32_t count = 1;
2076 // EnsureCapacity will guarantee the hash table is never full.
2077 while (true) {
2078 Object* element = KeyAt(entry);
2079 if (element == isolate->heap()->undefined_value()) break; // Empty entry.
2080 if (element != isolate->heap()->null_value() &&
2081 Shape::IsMatch(key, element)) return entry;
2082 entry = NextProbe(entry, count++, capacity);
2083 }
2084 return kNotFound;
2085}
2086
2087
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002088bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002089 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002090 if (!max_index_object->IsSmi()) return false;
2091 return 0 !=
2092 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2093}
2094
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002095uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002096 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002097 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002098 if (!max_index_object->IsSmi()) return 0;
2099 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2100 return value >> kRequiresSlowElementsTagSize;
2101}
2102
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002103void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002104 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002105}
2106
2107
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002108// ------------------------------------
2109// Cast operations
2110
2111
2112CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002113CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002114CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002115CAST_ACCESSOR(DeoptimizationInputData)
2116CAST_ACCESSOR(DeoptimizationOutputData)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002117CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002118CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002119CAST_ACCESSOR(NormalizedMapCache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002120CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002121CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002122CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002123CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002124CAST_ACCESSOR(String)
2125CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002126CAST_ACCESSOR(SeqAsciiString)
2127CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002128CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002129CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002130CAST_ACCESSOR(ExternalString)
2131CAST_ACCESSOR(ExternalAsciiString)
2132CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002133CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002134CAST_ACCESSOR(JSObject)
2135CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002136CAST_ACCESSOR(HeapObject)
2137CAST_ACCESSOR(HeapNumber)
2138CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002139CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002140CAST_ACCESSOR(SharedFunctionInfo)
2141CAST_ACCESSOR(Map)
2142CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002143CAST_ACCESSOR(GlobalObject)
2144CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002145CAST_ACCESSOR(JSGlobalObject)
2146CAST_ACCESSOR(JSBuiltinsObject)
2147CAST_ACCESSOR(Code)
2148CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002149CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002150CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002151CAST_ACCESSOR(JSFunctionProxy)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002152CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002153CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002154CAST_ACCESSOR(ByteArray)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002155CAST_ACCESSOR(FreeSpace)
ager@chromium.org3811b432009-10-28 14:53:37 +00002156CAST_ACCESSOR(ExternalArray)
2157CAST_ACCESSOR(ExternalByteArray)
2158CAST_ACCESSOR(ExternalUnsignedByteArray)
2159CAST_ACCESSOR(ExternalShortArray)
2160CAST_ACCESSOR(ExternalUnsignedShortArray)
2161CAST_ACCESSOR(ExternalIntArray)
2162CAST_ACCESSOR(ExternalUnsignedIntArray)
2163CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002164CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002165CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002166CAST_ACCESSOR(Struct)
2167
2168
2169#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2170 STRUCT_LIST(MAKE_STRUCT_CAST)
2171#undef MAKE_STRUCT_CAST
2172
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002173
2174template <typename Shape, typename Key>
2175HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002176 ASSERT(obj->IsHashTable());
2177 return reinterpret_cast<HashTable*>(obj);
2178}
2179
2180
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002181SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002182SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002183
ager@chromium.orgac091b72010-05-05 07:34:42 +00002184SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002185
2186
2187uint32_t String::hash_field() {
2188 return READ_UINT32_FIELD(this, kHashFieldOffset);
2189}
2190
2191
2192void String::set_hash_field(uint32_t value) {
2193 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002194#if V8_HOST_ARCH_64_BIT
2195 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2196#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002197}
2198
2199
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002200bool String::Equals(String* other) {
2201 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002202 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2203 return false;
2204 }
2205 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002206}
2207
2208
lrn@chromium.org303ada72010-10-27 09:33:13 +00002209MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002210 if (!StringShape(this).IsCons()) return this;
2211 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002212 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002213 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002214}
2215
2216
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002217String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002218 MaybeObject* flat = TryFlatten(pretenure);
2219 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002220 if (!flat->ToObject(&successfully_flattened)) return this;
2221 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002222}
2223
2224
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002225uint16_t String::Get(int index) {
2226 ASSERT(index >= 0 && index < length());
2227 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002228 case kSeqStringTag | kAsciiStringTag:
2229 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2230 case kSeqStringTag | kTwoByteStringTag:
2231 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2232 case kConsStringTag | kAsciiStringTag:
2233 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002234 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002235 case kExternalStringTag | kAsciiStringTag:
2236 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2237 case kExternalStringTag | kTwoByteStringTag:
2238 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002239 case kSlicedStringTag | kAsciiStringTag:
2240 case kSlicedStringTag | kTwoByteStringTag:
2241 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002242 default:
2243 break;
2244 }
2245
2246 UNREACHABLE();
2247 return 0;
2248}
2249
2250
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002251void String::Set(int index, uint16_t value) {
2252 ASSERT(index >= 0 && index < length());
2253 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002254
ager@chromium.org5ec48922009-05-05 07:25:34 +00002255 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002256 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2257 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002258}
2259
2260
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002261bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002262 if (!StringShape(this).IsCons()) return true;
2263 return ConsString::cast(this)->second()->length() == 0;
2264}
2265
2266
2267String* String::GetUnderlying() {
2268 // Giving direct access to underlying string only makes sense if the
2269 // wrapping string is already flattened.
2270 ASSERT(this->IsFlat());
2271 ASSERT(StringShape(this).IsIndirect());
2272 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2273 const int kUnderlyingOffset = SlicedString::kParentOffset;
2274 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002275}
2276
2277
ager@chromium.org7c537e22008-10-16 08:43:32 +00002278uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002279 ASSERT(index >= 0 && index < length());
2280 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2281}
2282
2283
ager@chromium.org7c537e22008-10-16 08:43:32 +00002284void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002285 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2286 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2287 static_cast<byte>(value));
2288}
2289
2290
ager@chromium.org7c537e22008-10-16 08:43:32 +00002291Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002292 return FIELD_ADDR(this, kHeaderSize);
2293}
2294
2295
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002296char* SeqAsciiString::GetChars() {
2297 return reinterpret_cast<char*>(GetCharsAddress());
2298}
2299
2300
ager@chromium.org7c537e22008-10-16 08:43:32 +00002301Address SeqTwoByteString::GetCharsAddress() {
2302 return FIELD_ADDR(this, kHeaderSize);
2303}
2304
2305
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002306uc16* SeqTwoByteString::GetChars() {
2307 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2308}
2309
2310
ager@chromium.org7c537e22008-10-16 08:43:32 +00002311uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002312 ASSERT(index >= 0 && index < length());
2313 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2314}
2315
2316
ager@chromium.org7c537e22008-10-16 08:43:32 +00002317void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002318 ASSERT(index >= 0 && index < length());
2319 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2320}
2321
2322
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002323int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002324 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002325}
2326
2327
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002328int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002329 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002330}
2331
2332
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002333String* SlicedString::parent() {
2334 return String::cast(READ_FIELD(this, kParentOffset));
2335}
2336
2337
2338void SlicedString::set_parent(String* parent) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002339 ASSERT(parent->IsSeqString() || parent->IsExternalString());
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002340 WRITE_FIELD(this, kParentOffset, parent);
2341}
2342
2343
2344SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2345
2346
ager@chromium.org870a0b62008-11-04 11:43:05 +00002347String* ConsString::first() {
2348 return String::cast(READ_FIELD(this, kFirstOffset));
2349}
2350
2351
2352Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002353 return READ_FIELD(this, kFirstOffset);
2354}
2355
2356
ager@chromium.org870a0b62008-11-04 11:43:05 +00002357void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002358 WRITE_FIELD(this, kFirstOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002359 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002360}
2361
2362
ager@chromium.org870a0b62008-11-04 11:43:05 +00002363String* ConsString::second() {
2364 return String::cast(READ_FIELD(this, kSecondOffset));
2365}
2366
2367
2368Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002369 return READ_FIELD(this, kSecondOffset);
2370}
2371
2372
ager@chromium.org870a0b62008-11-04 11:43:05 +00002373void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002374 WRITE_FIELD(this, kSecondOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002375 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002376}
2377
2378
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002379const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002380 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2381}
2382
2383
2384void ExternalAsciiString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002385 const ExternalAsciiString::Resource* resource) {
2386 *reinterpret_cast<const Resource**>(
2387 FIELD_ADDR(this, kResourceOffset)) = resource;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002388}
2389
2390
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002391const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002392 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2393}
2394
2395
2396void ExternalTwoByteString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002397 const ExternalTwoByteString::Resource* resource) {
2398 *reinterpret_cast<const Resource**>(
2399 FIELD_ADDR(this, kResourceOffset)) = resource;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002400}
2401
2402
ager@chromium.orgac091b72010-05-05 07:34:42 +00002403void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002404 set_finger_index(kEntriesIndex);
2405 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002406}
2407
2408
2409void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002410 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002411 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002412 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002413 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002414 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002415 MakeZeroSize();
2416}
2417
2418
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002419int JSFunctionResultCache::size() {
2420 return Smi::cast(get(kCacheSizeIndex))->value();
2421}
2422
2423
2424void JSFunctionResultCache::set_size(int size) {
2425 set(kCacheSizeIndex, Smi::FromInt(size));
2426}
2427
2428
2429int JSFunctionResultCache::finger_index() {
2430 return Smi::cast(get(kFingerIndex))->value();
2431}
2432
2433
2434void JSFunctionResultCache::set_finger_index(int finger_index) {
2435 set(kFingerIndex, Smi::FromInt(finger_index));
2436}
2437
2438
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002439byte ByteArray::get(int index) {
2440 ASSERT(index >= 0 && index < this->length());
2441 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2442}
2443
2444
2445void ByteArray::set(int index, byte value) {
2446 ASSERT(index >= 0 && index < this->length());
2447 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2448}
2449
2450
2451int ByteArray::get_int(int index) {
2452 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2453 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2454}
2455
2456
2457ByteArray* ByteArray::FromDataStartAddress(Address address) {
2458 ASSERT_TAG_ALIGNED(address);
2459 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2460}
2461
2462
2463Address ByteArray::GetDataStartAddress() {
2464 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2465}
2466
2467
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002468uint8_t* ExternalPixelArray::external_pixel_pointer() {
2469 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002470}
2471
2472
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002473uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002474 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002475 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002476 return ptr[index];
2477}
2478
2479
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002480MaybeObject* ExternalPixelArray::get(int index) {
2481 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2482}
2483
2484
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002485void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002486 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002487 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002488 ptr[index] = value;
2489}
2490
2491
ager@chromium.org3811b432009-10-28 14:53:37 +00002492void* ExternalArray::external_pointer() {
2493 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2494 return reinterpret_cast<void*>(ptr);
2495}
2496
2497
2498void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2499 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2500 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2501}
2502
2503
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002504int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002505 ASSERT((index >= 0) && (index < this->length()));
2506 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2507 return ptr[index];
2508}
2509
2510
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002511MaybeObject* ExternalByteArray::get(int index) {
2512 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2513}
2514
2515
ager@chromium.org3811b432009-10-28 14:53:37 +00002516void ExternalByteArray::set(int index, int8_t value) {
2517 ASSERT((index >= 0) && (index < this->length()));
2518 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2519 ptr[index] = value;
2520}
2521
2522
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002523uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002524 ASSERT((index >= 0) && (index < this->length()));
2525 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2526 return ptr[index];
2527}
2528
2529
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002530MaybeObject* ExternalUnsignedByteArray::get(int index) {
2531 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2532}
2533
2534
ager@chromium.org3811b432009-10-28 14:53:37 +00002535void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2536 ASSERT((index >= 0) && (index < this->length()));
2537 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2538 ptr[index] = value;
2539}
2540
2541
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002542int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002543 ASSERT((index >= 0) && (index < this->length()));
2544 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2545 return ptr[index];
2546}
2547
2548
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002549MaybeObject* ExternalShortArray::get(int index) {
2550 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2551}
2552
2553
ager@chromium.org3811b432009-10-28 14:53:37 +00002554void ExternalShortArray::set(int index, int16_t value) {
2555 ASSERT((index >= 0) && (index < this->length()));
2556 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2557 ptr[index] = value;
2558}
2559
2560
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002561uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002562 ASSERT((index >= 0) && (index < this->length()));
2563 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2564 return ptr[index];
2565}
2566
2567
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002568MaybeObject* ExternalUnsignedShortArray::get(int index) {
2569 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2570}
2571
2572
ager@chromium.org3811b432009-10-28 14:53:37 +00002573void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2574 ASSERT((index >= 0) && (index < this->length()));
2575 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2576 ptr[index] = value;
2577}
2578
2579
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002580int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002581 ASSERT((index >= 0) && (index < this->length()));
2582 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2583 return ptr[index];
2584}
2585
2586
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002587MaybeObject* ExternalIntArray::get(int index) {
2588 return GetHeap()->NumberFromInt32(get_scalar(index));
2589}
2590
2591
ager@chromium.org3811b432009-10-28 14:53:37 +00002592void ExternalIntArray::set(int index, int32_t value) {
2593 ASSERT((index >= 0) && (index < this->length()));
2594 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2595 ptr[index] = value;
2596}
2597
2598
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002599uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002600 ASSERT((index >= 0) && (index < this->length()));
2601 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2602 return ptr[index];
2603}
2604
2605
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002606MaybeObject* ExternalUnsignedIntArray::get(int index) {
2607 return GetHeap()->NumberFromUint32(get_scalar(index));
2608}
2609
2610
ager@chromium.org3811b432009-10-28 14:53:37 +00002611void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2612 ASSERT((index >= 0) && (index < this->length()));
2613 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2614 ptr[index] = value;
2615}
2616
2617
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002618float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002619 ASSERT((index >= 0) && (index < this->length()));
2620 float* ptr = static_cast<float*>(external_pointer());
2621 return ptr[index];
2622}
2623
2624
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002625MaybeObject* ExternalFloatArray::get(int index) {
2626 return GetHeap()->NumberFromDouble(get_scalar(index));
2627}
2628
2629
ager@chromium.org3811b432009-10-28 14:53:37 +00002630void ExternalFloatArray::set(int index, float value) {
2631 ASSERT((index >= 0) && (index < this->length()));
2632 float* ptr = static_cast<float*>(external_pointer());
2633 ptr[index] = value;
2634}
2635
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002636
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002637double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002638 ASSERT((index >= 0) && (index < this->length()));
2639 double* ptr = static_cast<double*>(external_pointer());
2640 return ptr[index];
2641}
2642
2643
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002644MaybeObject* ExternalDoubleArray::get(int index) {
2645 return GetHeap()->NumberFromDouble(get_scalar(index));
2646}
2647
2648
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002649void ExternalDoubleArray::set(int index, double value) {
2650 ASSERT((index >= 0) && (index < this->length()));
2651 double* ptr = static_cast<double*>(external_pointer());
2652 ptr[index] = value;
2653}
2654
2655
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002656int Map::visitor_id() {
2657 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2658}
2659
2660
2661void Map::set_visitor_id(int id) {
2662 ASSERT(0 <= id && id < 256);
2663 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2664}
2665
ager@chromium.org3811b432009-10-28 14:53:37 +00002666
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002667int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002668 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2669}
2670
2671
2672int Map::inobject_properties() {
2673 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002674}
2675
2676
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002677int Map::pre_allocated_property_fields() {
2678 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2679}
2680
2681
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002682int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002683 int instance_size = map->instance_size();
2684 if (instance_size != kVariableSizeSentinel) return instance_size;
2685 // We can ignore the "symbol" bit becase it is only set for symbols
2686 // and implies a string type.
2687 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002688 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002689 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002690 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002691 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002692 if (instance_type == ASCII_STRING_TYPE) {
2693 return SeqAsciiString::SizeFor(
2694 reinterpret_cast<SeqAsciiString*>(this)->length());
2695 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002696 if (instance_type == BYTE_ARRAY_TYPE) {
2697 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2698 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002699 if (instance_type == FREE_SPACE_TYPE) {
2700 return reinterpret_cast<FreeSpace*>(this)->size();
2701 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002702 if (instance_type == STRING_TYPE) {
2703 return SeqTwoByteString::SizeFor(
2704 reinterpret_cast<SeqTwoByteString*>(this)->length());
2705 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002706 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2707 return FixedDoubleArray::SizeFor(
2708 reinterpret_cast<FixedDoubleArray*>(this)->length());
2709 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002710 ASSERT(instance_type == CODE_TYPE);
2711 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002712}
2713
2714
2715void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002716 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002717 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002718 ASSERT(0 <= value && value < 256);
2719 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2720}
2721
2722
ager@chromium.org7c537e22008-10-16 08:43:32 +00002723void Map::set_inobject_properties(int value) {
2724 ASSERT(0 <= value && value < 256);
2725 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2726}
2727
2728
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002729void Map::set_pre_allocated_property_fields(int value) {
2730 ASSERT(0 <= value && value < 256);
2731 WRITE_BYTE_FIELD(this,
2732 kPreAllocatedPropertyFieldsOffset,
2733 static_cast<byte>(value));
2734}
2735
2736
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002737InstanceType Map::instance_type() {
2738 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2739}
2740
2741
2742void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002743 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2744}
2745
2746
2747int Map::unused_property_fields() {
2748 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2749}
2750
2751
2752void Map::set_unused_property_fields(int value) {
2753 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2754}
2755
2756
2757byte Map::bit_field() {
2758 return READ_BYTE_FIELD(this, kBitFieldOffset);
2759}
2760
2761
2762void Map::set_bit_field(byte value) {
2763 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2764}
2765
2766
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002767byte Map::bit_field2() {
2768 return READ_BYTE_FIELD(this, kBitField2Offset);
2769}
2770
2771
2772void Map::set_bit_field2(byte value) {
2773 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2774}
2775
2776
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002777void Map::set_non_instance_prototype(bool value) {
2778 if (value) {
2779 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2780 } else {
2781 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2782 }
2783}
2784
2785
2786bool Map::has_non_instance_prototype() {
2787 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2788}
2789
2790
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002791void Map::set_function_with_prototype(bool value) {
2792 if (value) {
2793 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2794 } else {
2795 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2796 }
2797}
2798
2799
2800bool Map::function_with_prototype() {
2801 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2802}
2803
2804
ager@chromium.org870a0b62008-11-04 11:43:05 +00002805void Map::set_is_access_check_needed(bool access_check_needed) {
2806 if (access_check_needed) {
2807 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2808 } else {
2809 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2810 }
2811}
2812
2813
2814bool Map::is_access_check_needed() {
2815 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2816}
2817
2818
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002819void Map::set_is_extensible(bool value) {
2820 if (value) {
2821 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2822 } else {
2823 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2824 }
2825}
2826
2827bool Map::is_extensible() {
2828 return ((1 << kIsExtensible) & bit_field2()) != 0;
2829}
2830
2831
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002832void Map::set_attached_to_shared_function_info(bool value) {
2833 if (value) {
2834 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2835 } else {
2836 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2837 }
2838}
2839
2840bool Map::attached_to_shared_function_info() {
2841 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2842}
2843
2844
2845void Map::set_is_shared(bool value) {
2846 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002847 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002848 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002849 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002850 }
2851}
2852
2853bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002854 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002855}
2856
2857
2858JSFunction* Map::unchecked_constructor() {
2859 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2860}
2861
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002862
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002863Code::Flags Code::flags() {
2864 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2865}
2866
2867
2868void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002869 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002870 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002871 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2872 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002873 ExtractArgumentsCountFromFlags(flags) >= 0);
2874 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2875}
2876
2877
2878Code::Kind Code::kind() {
2879 return ExtractKindFromFlags(flags());
2880}
2881
2882
kasper.lund7276f142008-07-30 08:49:36 +00002883InlineCacheState Code::ic_state() {
2884 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002885 // Only allow uninitialized or debugger states for non-IC code
2886 // objects. This is used in the debugger to determine whether or not
2887 // a call to code object has been replaced with a debug break call.
2888 ASSERT(is_inline_cache_stub() ||
2889 result == UNINITIALIZED ||
2890 result == DEBUG_BREAK ||
2891 result == DEBUG_PREPARE_STEP_IN);
2892 return result;
2893}
2894
2895
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002896Code::ExtraICState Code::extra_ic_state() {
2897 ASSERT(is_inline_cache_stub());
2898 return ExtractExtraICStateFromFlags(flags());
2899}
2900
2901
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002902PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002903 return ExtractTypeFromFlags(flags());
2904}
2905
2906
2907int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002908 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002909 return ExtractArgumentsCountFromFlags(flags());
2910}
2911
2912
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002913int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002914 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002915 kind() == UNARY_OP_IC ||
2916 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002917 kind() == COMPARE_IC ||
2918 kind() == TO_BOOLEAN_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002919 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002920}
2921
2922
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002923void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002924 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002925 kind() == UNARY_OP_IC ||
2926 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002927 kind() == COMPARE_IC ||
2928 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002929 ASSERT(0 <= major && major < 256);
2930 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002931}
2932
2933
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002934bool Code::is_pregenerated() {
2935 return kind() == STUB && IsPregeneratedField::decode(flags());
2936}
2937
2938
2939void Code::set_is_pregenerated(bool value) {
2940 ASSERT(kind() == STUB);
2941 Flags f = flags();
2942 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
2943 set_flags(f);
2944}
2945
2946
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002947bool Code::optimizable() {
2948 ASSERT(kind() == FUNCTION);
2949 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2950}
2951
2952
2953void Code::set_optimizable(bool value) {
2954 ASSERT(kind() == FUNCTION);
2955 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2956}
2957
2958
2959bool Code::has_deoptimization_support() {
2960 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00002961 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2962 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002963}
2964
2965
2966void Code::set_has_deoptimization_support(bool value) {
2967 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00002968 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2969 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
2970 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
2971}
2972
2973
2974bool Code::has_debug_break_slots() {
2975 ASSERT(kind() == FUNCTION);
2976 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2977 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
2978}
2979
2980
2981void Code::set_has_debug_break_slots(bool value) {
2982 ASSERT(kind() == FUNCTION);
2983 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2984 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
2985 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002986}
2987
2988
2989int Code::allow_osr_at_loop_nesting_level() {
2990 ASSERT(kind() == FUNCTION);
2991 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
2992}
2993
2994
2995void Code::set_allow_osr_at_loop_nesting_level(int level) {
2996 ASSERT(kind() == FUNCTION);
2997 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
2998 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
2999}
3000
3001
3002unsigned Code::stack_slots() {
3003 ASSERT(kind() == OPTIMIZED_FUNCTION);
3004 return READ_UINT32_FIELD(this, kStackSlotsOffset);
3005}
3006
3007
3008void Code::set_stack_slots(unsigned slots) {
3009 ASSERT(kind() == OPTIMIZED_FUNCTION);
3010 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
3011}
3012
3013
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003014unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003015 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003016 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003017}
3018
3019
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003020void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003021 ASSERT(kind() == OPTIMIZED_FUNCTION);
3022 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003023 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003024}
3025
3026
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003027unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003028 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003029 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003030}
3031
3032
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003033void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003034 ASSERT(kind() == FUNCTION);
3035 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003036 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003037}
3038
3039
3040CheckType Code::check_type() {
3041 ASSERT(is_call_stub() || is_keyed_call_stub());
3042 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3043 return static_cast<CheckType>(type);
3044}
3045
3046
3047void Code::set_check_type(CheckType value) {
3048 ASSERT(is_call_stub() || is_keyed_call_stub());
3049 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3050}
3051
3052
danno@chromium.org40cb8782011-05-25 07:58:50 +00003053byte Code::unary_op_type() {
3054 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003055 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
3056}
3057
3058
danno@chromium.org40cb8782011-05-25 07:58:50 +00003059void Code::set_unary_op_type(byte value) {
3060 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003061 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
3062}
3063
3064
danno@chromium.org40cb8782011-05-25 07:58:50 +00003065byte Code::binary_op_type() {
3066 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003067 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
3068}
3069
3070
danno@chromium.org40cb8782011-05-25 07:58:50 +00003071void Code::set_binary_op_type(byte value) {
3072 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003073 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
3074}
3075
3076
danno@chromium.org40cb8782011-05-25 07:58:50 +00003077byte Code::binary_op_result_type() {
3078 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003079 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
3080}
3081
3082
danno@chromium.org40cb8782011-05-25 07:58:50 +00003083void Code::set_binary_op_result_type(byte value) {
3084 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003085 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
3086}
3087
3088
3089byte Code::compare_state() {
3090 ASSERT(is_compare_ic_stub());
3091 return READ_BYTE_FIELD(this, kCompareStateOffset);
3092}
3093
3094
3095void Code::set_compare_state(byte value) {
3096 ASSERT(is_compare_ic_stub());
3097 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
3098}
3099
3100
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003101byte Code::to_boolean_state() {
3102 ASSERT(is_to_boolean_ic_stub());
3103 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
3104}
3105
3106
3107void Code::set_to_boolean_state(byte value) {
3108 ASSERT(is_to_boolean_ic_stub());
3109 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
3110}
3111
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003112
3113bool Code::has_function_cache() {
3114 ASSERT(kind() == STUB);
3115 return READ_BYTE_FIELD(this, kHasFunctionCacheOffset) != 0;
3116}
3117
3118
3119void Code::set_has_function_cache(bool flag) {
3120 ASSERT(kind() == STUB);
3121 WRITE_BYTE_FIELD(this, kHasFunctionCacheOffset, flag);
3122}
3123
3124
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003125bool Code::is_inline_cache_stub() {
3126 Kind kind = this->kind();
3127 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3128}
3129
3130
3131Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003132 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003133 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003134 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003135 int argc,
3136 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003137 // Extra IC state is only allowed for call IC stubs or for store IC
3138 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003139 ASSERT(extra_ic_state == kNoExtraICState ||
lrn@chromium.org34e60782011-09-15 07:25:40 +00003140 kind == CALL_IC ||
3141 kind == STORE_IC ||
3142 kind == KEYED_STORE_IC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003143 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003144 int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003145 | ICStateField::encode(ic_state)
3146 | TypeField::encode(type)
3147 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003148 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003149 | CacheHolderField::encode(holder);
3150 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003151}
3152
3153
3154Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
3155 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003156 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003157 InlineCacheHolderFlag holder,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003158 int argc) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003159 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003160}
3161
3162
3163Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003164 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003165}
3166
3167
kasper.lund7276f142008-07-30 08:49:36 +00003168InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003169 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003170}
3171
3172
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003173Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003174 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003175}
3176
3177
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003178PropertyType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003179 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003180}
3181
3182
3183int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003184 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003185}
3186
3187
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003188InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003189 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003190}
3191
3192
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003193Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003194 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003195 return static_cast<Flags>(bits);
3196}
3197
3198
ager@chromium.org8bb60582008-12-11 12:02:20 +00003199Code* Code::GetCodeFromTargetAddress(Address address) {
3200 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3201 // GetCodeFromTargetAddress might be called when marking objects during mark
3202 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3203 // Code::cast. Code::cast does not work when the object's map is
3204 // marked.
3205 Code* result = reinterpret_cast<Code*>(code);
3206 return result;
3207}
3208
3209
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003210Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3211 return HeapObject::
3212 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3213}
3214
3215
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003216Object* Map::prototype() {
3217 return READ_FIELD(this, kPrototypeOffset);
3218}
3219
3220
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003221void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003222 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003223 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003224 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003225}
3226
3227
danno@chromium.org40cb8782011-05-25 07:58:50 +00003228DescriptorArray* Map::instance_descriptors() {
3229 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3230 if (object->IsSmi()) {
3231 return HEAP->empty_descriptor_array();
3232 } else {
3233 return DescriptorArray::cast(object);
3234 }
3235}
3236
3237
3238void Map::init_instance_descriptors() {
3239 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3240}
3241
3242
3243void Map::clear_instance_descriptors() {
3244 Object* object = READ_FIELD(this,
3245 kInstanceDescriptorsOrBitField3Offset);
3246 if (!object->IsSmi()) {
3247 WRITE_FIELD(
3248 this,
3249 kInstanceDescriptorsOrBitField3Offset,
3250 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3251 }
3252}
3253
3254
3255void Map::set_instance_descriptors(DescriptorArray* value,
3256 WriteBarrierMode mode) {
3257 Object* object = READ_FIELD(this,
3258 kInstanceDescriptorsOrBitField3Offset);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003259 Heap* heap = GetHeap();
3260 if (value == heap->empty_descriptor_array()) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003261 clear_instance_descriptors();
3262 return;
3263 } else {
3264 if (object->IsSmi()) {
3265 value->set_bit_field3_storage(Smi::cast(object)->value());
3266 } else {
3267 value->set_bit_field3_storage(
3268 DescriptorArray::cast(object)->bit_field3_storage());
3269 }
3270 }
3271 ASSERT(!is_shared());
3272 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003273 CONDITIONAL_WRITE_BARRIER(
3274 heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003275}
3276
3277
3278int Map::bit_field3() {
3279 Object* object = READ_FIELD(this,
3280 kInstanceDescriptorsOrBitField3Offset);
3281 if (object->IsSmi()) {
3282 return Smi::cast(object)->value();
3283 } else {
3284 return DescriptorArray::cast(object)->bit_field3_storage();
3285 }
3286}
3287
3288
3289void Map::set_bit_field3(int value) {
3290 ASSERT(Smi::IsValid(value));
3291 Object* object = READ_FIELD(this,
3292 kInstanceDescriptorsOrBitField3Offset);
3293 if (object->IsSmi()) {
3294 WRITE_FIELD(this,
3295 kInstanceDescriptorsOrBitField3Offset,
3296 Smi::FromInt(value));
3297 } else {
3298 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3299 }
3300}
3301
3302
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003303FixedArray* Map::unchecked_prototype_transitions() {
3304 return reinterpret_cast<FixedArray*>(
3305 READ_FIELD(this, kPrototypeTransitionsOffset));
3306}
3307
3308
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003309ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003310ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003311ACCESSORS(Map, constructor, Object, kConstructorOffset)
3312
3313ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
3314ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003315ACCESSORS(JSFunction,
3316 next_function_link,
3317 Object,
3318 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003319
3320ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3321ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003322ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003323
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003324ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003325
3326ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3327ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3328ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3329ACCESSORS(AccessorInfo, name, Object, kNameOffset)
3330ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
3331
3332ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3333ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3334ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3335
3336ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3337ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3338ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3339ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3340ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3341ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3342
3343ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3344ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3345
3346ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3347ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3348
3349ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3350ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003351ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3352 kPropertyAccessorsOffset)
3353ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3354 kPrototypeTemplateOffset)
3355ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3356ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3357 kNamedPropertyHandlerOffset)
3358ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3359 kIndexedPropertyHandlerOffset)
3360ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3361 kInstanceTemplateOffset)
3362ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3363ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003364ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3365 kInstanceCallHandlerOffset)
3366ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3367 kAccessCheckInfoOffset)
3368ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
3369
3370ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003371ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3372 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003373
3374ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3375ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3376
3377ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3378
3379ACCESSORS(Script, source, Object, kSourceOffset)
3380ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003381ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003382ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3383ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003384ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003385ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003386ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003387ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003388ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003389ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003390ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003391ACCESSORS(Script, eval_from_instructions_offset, Smi,
3392 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003393
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003394#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003395ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3396ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3397ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3398ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3399
3400ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3401ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3402ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3403ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003404#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003405
3406ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003407ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3408ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003409ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3410 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003411ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003412ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3413ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003414ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003415ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3416 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003417
3418BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3419 kHiddenPrototypeBit)
3420BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3421BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3422 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003423BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3424 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003425BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3426 kIsExpressionBit)
3427BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3428 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003429BOOL_GETTER(SharedFunctionInfo,
3430 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003431 has_only_simple_this_property_assignments,
3432 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003433BOOL_ACCESSORS(SharedFunctionInfo,
3434 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003435 allows_lazy_compilation,
3436 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003437BOOL_ACCESSORS(SharedFunctionInfo,
3438 compiler_hints,
3439 uses_arguments,
3440 kUsesArguments)
3441BOOL_ACCESSORS(SharedFunctionInfo,
3442 compiler_hints,
3443 has_duplicate_parameters,
3444 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003445
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003446
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003447#if V8_HOST_ARCH_32_BIT
3448SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3449SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003450 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003451SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003452 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003453SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3454SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003455 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003456SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3457SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003458 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003459SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003460 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003461SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003462 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003463SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003464#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003465
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003466#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003467 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003468 int holder::name() { \
3469 int value = READ_INT_FIELD(this, offset); \
3470 ASSERT(kHeapObjectTag == 1); \
3471 ASSERT((value & kHeapObjectTag) == 0); \
3472 return value >> 1; \
3473 } \
3474 void holder::set_##name(int value) { \
3475 ASSERT(kHeapObjectTag == 1); \
3476 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3477 (value & 0xC0000000) == 0x000000000); \
3478 WRITE_INT_FIELD(this, \
3479 offset, \
3480 (value << 1) & ~kHeapObjectTag); \
3481 }
3482
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003483#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3484 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003485 INT_ACCESSORS(holder, name, offset)
3486
3487
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003488PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003489PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3490 formal_parameter_count,
3491 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003492
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003493PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3494 expected_nof_properties,
3495 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003496PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3497
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003498PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3499PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3500 start_position_and_type,
3501 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003502
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003503PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3504 function_token_position,
3505 kFunctionTokenPositionOffset)
3506PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3507 compiler_hints,
3508 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003509
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003510PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3511 this_property_assignments_count,
3512 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003513PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003514#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003515
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003516
3517int SharedFunctionInfo::construction_count() {
3518 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3519}
3520
3521
3522void SharedFunctionInfo::set_construction_count(int value) {
3523 ASSERT(0 <= value && value < 256);
3524 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3525}
3526
3527
whesse@chromium.org7b260152011-06-20 15:33:18 +00003528BOOL_ACCESSORS(SharedFunctionInfo,
3529 compiler_hints,
3530 live_objects_may_exist,
3531 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003532
3533
3534bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003535 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003536}
3537
3538
whesse@chromium.org7b260152011-06-20 15:33:18 +00003539BOOL_GETTER(SharedFunctionInfo,
3540 compiler_hints,
3541 optimization_disabled,
3542 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003543
3544
3545void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3546 set_compiler_hints(BooleanBit::set(compiler_hints(),
3547 kOptimizationDisabled,
3548 disable));
3549 // If disabling optimizations we reflect that in the code object so
3550 // it will not be counted as optimizable code.
3551 if ((code()->kind() == Code::FUNCTION) && disable) {
3552 code()->set_optimizable(false);
3553 }
3554}
3555
3556
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003557BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, strict_mode,
whesse@chromium.org7b260152011-06-20 15:33:18 +00003558 kStrictModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003559BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3560BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3561 name_should_print_as_anonymous,
3562 kNameShouldPrintAsAnonymous)
3563BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3564BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003565
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003566ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3567ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3568
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003569ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3570
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003571bool Script::HasValidSource() {
3572 Object* src = this->source();
3573 if (!src->IsString()) return true;
3574 String* src_str = String::cast(src);
3575 if (!StringShape(src_str).IsExternal()) return true;
3576 if (src_str->IsAsciiRepresentation()) {
3577 return ExternalAsciiString::cast(src)->resource() != NULL;
3578 } else if (src_str->IsTwoByteRepresentation()) {
3579 return ExternalTwoByteString::cast(src)->resource() != NULL;
3580 }
3581 return true;
3582}
3583
3584
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003585void SharedFunctionInfo::DontAdaptArguments() {
3586 ASSERT(code()->kind() == Code::BUILTIN);
3587 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3588}
3589
3590
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003591int SharedFunctionInfo::start_position() {
3592 return start_position_and_type() >> kStartPositionShift;
3593}
3594
3595
3596void SharedFunctionInfo::set_start_position(int start_position) {
3597 set_start_position_and_type((start_position << kStartPositionShift)
3598 | (start_position_and_type() & ~kStartPositionMask));
3599}
3600
3601
3602Code* SharedFunctionInfo::code() {
3603 return Code::cast(READ_FIELD(this, kCodeOffset));
3604}
3605
3606
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003607Code* SharedFunctionInfo::unchecked_code() {
3608 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3609}
3610
3611
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003612void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003613 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003614 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003615}
3616
3617
ager@chromium.orgb5737492010-07-15 09:29:43 +00003618SerializedScopeInfo* SharedFunctionInfo::scope_info() {
3619 return reinterpret_cast<SerializedScopeInfo*>(
3620 READ_FIELD(this, kScopeInfoOffset));
3621}
3622
3623
3624void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
3625 WriteBarrierMode mode) {
3626 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003627 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3628 this,
3629 kScopeInfoOffset,
3630 reinterpret_cast<Object*>(value),
3631 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003632}
3633
3634
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003635Smi* SharedFunctionInfo::deopt_counter() {
3636 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3637}
3638
3639
3640void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3641 WRITE_FIELD(this, kDeoptCounterOffset, value);
3642}
3643
3644
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003645bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003646 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003647 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003648}
3649
3650
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003651bool SharedFunctionInfo::IsApiFunction() {
3652 return function_data()->IsFunctionTemplateInfo();
3653}
3654
3655
3656FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3657 ASSERT(IsApiFunction());
3658 return FunctionTemplateInfo::cast(function_data());
3659}
3660
3661
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003662bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003663 return function_data()->IsSmi();
3664}
3665
3666
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003667BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3668 ASSERT(HasBuiltinFunctionId());
3669 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003670}
3671
3672
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003673int SharedFunctionInfo::code_age() {
3674 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3675}
3676
3677
3678void SharedFunctionInfo::set_code_age(int code_age) {
3679 set_compiler_hints(compiler_hints() |
3680 ((code_age & kCodeAgeMask) << kCodeAgeShift));
3681}
3682
3683
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003684bool SharedFunctionInfo::has_deoptimization_support() {
3685 Code* code = this->code();
3686 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3687}
3688
3689
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003690bool JSFunction::IsBuiltin() {
3691 return context()->global()->IsJSBuiltinsObject();
3692}
3693
3694
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003695bool JSFunction::NeedsArgumentsAdaption() {
3696 return shared()->formal_parameter_count() !=
3697 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3698}
3699
3700
3701bool JSFunction::IsOptimized() {
3702 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3703}
3704
3705
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003706bool JSFunction::IsOptimizable() {
3707 return code()->kind() == Code::FUNCTION && code()->optimizable();
3708}
3709
3710
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003711bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003712 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003713}
3714
3715
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003716Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003717 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003718}
3719
3720
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003721Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003722 return reinterpret_cast<Code*>(
3723 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003724}
3725
3726
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003727void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003728 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003729 Address entry = value->entry();
3730 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003731 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
3732 this,
3733 HeapObject::RawField(this, kCodeEntryOffset),
3734 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003735}
3736
3737
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003738void JSFunction::ReplaceCode(Code* code) {
3739 bool was_optimized = IsOptimized();
3740 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3741
3742 set_code(code);
3743
3744 // Add/remove the function from the list of optimized functions for this
3745 // context based on the state change.
3746 if (!was_optimized && is_optimized) {
3747 context()->global_context()->AddOptimizedFunction(this);
3748 }
3749 if (was_optimized && !is_optimized) {
3750 context()->global_context()->RemoveOptimizedFunction(this);
3751 }
3752}
3753
3754
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003755Context* JSFunction::context() {
3756 return Context::cast(READ_FIELD(this, kContextOffset));
3757}
3758
3759
3760Object* JSFunction::unchecked_context() {
3761 return READ_FIELD(this, kContextOffset);
3762}
3763
3764
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003765SharedFunctionInfo* JSFunction::unchecked_shared() {
3766 return reinterpret_cast<SharedFunctionInfo*>(
3767 READ_FIELD(this, kSharedFunctionInfoOffset));
3768}
3769
3770
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003771void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003772 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003773 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003774 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003775}
3776
3777ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3778 kPrototypeOrInitialMapOffset)
3779
3780
3781Map* JSFunction::initial_map() {
3782 return Map::cast(prototype_or_initial_map());
3783}
3784
3785
3786void JSFunction::set_initial_map(Map* value) {
3787 set_prototype_or_initial_map(value);
3788}
3789
3790
3791bool JSFunction::has_initial_map() {
3792 return prototype_or_initial_map()->IsMap();
3793}
3794
3795
3796bool JSFunction::has_instance_prototype() {
3797 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3798}
3799
3800
3801bool JSFunction::has_prototype() {
3802 return map()->has_non_instance_prototype() || has_instance_prototype();
3803}
3804
3805
3806Object* JSFunction::instance_prototype() {
3807 ASSERT(has_instance_prototype());
3808 if (has_initial_map()) return initial_map()->prototype();
3809 // When there is no initial map and the prototype is a JSObject, the
3810 // initial map field is used for the prototype field.
3811 return prototype_or_initial_map();
3812}
3813
3814
3815Object* JSFunction::prototype() {
3816 ASSERT(has_prototype());
3817 // If the function's prototype property has been set to a non-JSObject
3818 // value, that value is stored in the constructor field of the map.
3819 if (map()->has_non_instance_prototype()) return map()->constructor();
3820 return instance_prototype();
3821}
3822
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003823bool JSFunction::should_have_prototype() {
3824 return map()->function_with_prototype();
3825}
3826
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003827
3828bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003829 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003830}
3831
3832
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003833int JSFunction::NumberOfLiterals() {
3834 return literals()->length();
3835}
3836
3837
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003838Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003839 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003840 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003841}
3842
3843
3844void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3845 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003846 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003847 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003848 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003849}
3850
3851
3852Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003853 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003854 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3855}
3856
3857
3858void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3859 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003860 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003861 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003862 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003863}
3864
3865
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003866ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003867ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003868ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
3869ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
3870
3871
3872void JSProxy::InitializeBody(int object_size, Object* value) {
3873 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
3874 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
3875 WRITE_FIELD(this, offset, value);
3876 }
3877}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003878
3879
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003880ACCESSORS(JSWeakMap, table, Object, kTableOffset)
3881ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003882
3883
3884ObjectHashTable* JSWeakMap::unchecked_table() {
3885 return reinterpret_cast<ObjectHashTable*>(READ_FIELD(this, kTableOffset));
3886}
3887
3888
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003889Address Foreign::address() {
3890 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003891}
3892
3893
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003894void Foreign::set_address(Address value) {
3895 WRITE_INTPTR_FIELD(this, kAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003896}
3897
3898
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003899ACCESSORS(JSValue, value, Object, kValueOffset)
3900
3901
3902JSValue* JSValue::cast(Object* obj) {
3903 ASSERT(obj->IsJSValue());
3904 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3905 return reinterpret_cast<JSValue*>(obj);
3906}
3907
3908
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003909ACCESSORS(JSMessageObject, type, String, kTypeOffset)
3910ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
3911ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
3912ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
3913ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
3914SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
3915SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
3916
3917
3918JSMessageObject* JSMessageObject::cast(Object* obj) {
3919 ASSERT(obj->IsJSMessageObject());
3920 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
3921 return reinterpret_cast<JSMessageObject*>(obj);
3922}
3923
3924
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003925INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003926ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003927ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003928ACCESSORS(Code, next_code_flushing_candidate,
3929 Object, kNextCodeFlushingCandidateOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003930
3931
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003932byte* Code::instruction_start() {
3933 return FIELD_ADDR(this, kHeaderSize);
3934}
3935
3936
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003937byte* Code::instruction_end() {
3938 return instruction_start() + instruction_size();
3939}
3940
3941
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003942int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003943 return RoundUp(instruction_size(), kObjectAlignment);
3944}
3945
3946
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003947FixedArray* Code::unchecked_deoptimization_data() {
3948 return reinterpret_cast<FixedArray*>(
3949 READ_FIELD(this, kDeoptimizationDataOffset));
3950}
3951
3952
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003953ByteArray* Code::unchecked_relocation_info() {
3954 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003955}
3956
3957
3958byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003959 return unchecked_relocation_info()->GetDataStartAddress();
3960}
3961
3962
3963int Code::relocation_size() {
3964 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003965}
3966
3967
3968byte* Code::entry() {
3969 return instruction_start();
3970}
3971
3972
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003973bool Code::contains(byte* inner_pointer) {
3974 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003975}
3976
3977
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003978ACCESSORS(JSArray, length, Object, kLengthOffset)
3979
3980
ager@chromium.org236ad962008-09-25 09:45:57 +00003981ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00003982
3983
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003984JSRegExp::Type JSRegExp::TypeTag() {
3985 Object* data = this->data();
3986 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
3987 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
3988 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00003989}
3990
3991
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003992JSRegExp::Type JSRegExp::TypeTagUnchecked() {
3993 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
3994 return static_cast<JSRegExp::Type>(smi->value());
3995}
3996
3997
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00003998int JSRegExp::CaptureCount() {
3999 switch (TypeTag()) {
4000 case ATOM:
4001 return 0;
4002 case IRREGEXP:
4003 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
4004 default:
4005 UNREACHABLE();
4006 return -1;
4007 }
4008}
4009
4010
ager@chromium.orga74f0da2008-12-03 16:05:52 +00004011JSRegExp::Flags JSRegExp::GetFlags() {
4012 ASSERT(this->data()->IsFixedArray());
4013 Object* data = this->data();
4014 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4015 return Flags(smi->value());
4016}
4017
4018
4019String* JSRegExp::Pattern() {
4020 ASSERT(this->data()->IsFixedArray());
4021 Object* data = this->data();
4022 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4023 return pattern;
4024}
4025
4026
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004027Object* JSRegExp::DataAt(int index) {
4028 ASSERT(TypeTag() != NOT_COMPILED);
4029 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004030}
4031
4032
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004033Object* JSRegExp::DataAtUnchecked(int index) {
4034 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4035 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4036 return READ_FIELD(fa, offset);
4037}
4038
4039
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004040void JSRegExp::SetDataAt(int index, Object* value) {
4041 ASSERT(TypeTag() != NOT_COMPILED);
4042 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4043 FixedArray::cast(data())->set(index, value);
4044}
4045
4046
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004047void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4048 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4049 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4050 if (value->IsSmi()) {
4051 fa->set_unchecked(index, Smi::cast(value));
4052 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004053 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004054 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4055 }
4056}
4057
4058
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004059ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004060 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004061#if DEBUG
4062 FixedArrayBase* fixed_array =
4063 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4064 Map* map = fixed_array->map();
4065 ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) &&
4066 (map == GetHeap()->fixed_array_map() ||
4067 map == GetHeap()->fixed_cow_array_map())) ||
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004068 (kind == FAST_DOUBLE_ELEMENTS &&
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004069 fixed_array->IsFixedDoubleArray()) ||
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004070 (kind == DICTIONARY_ELEMENTS &&
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004071 fixed_array->IsFixedArray() &&
4072 fixed_array->IsDictionary()) ||
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004073 (kind > DICTIONARY_ELEMENTS));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004074#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004075 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004076}
4077
4078
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004079ElementsAccessor* JSObject::GetElementsAccessor() {
4080 return ElementsAccessor::ForKind(GetElementsKind());
4081}
4082
4083
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004084bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004085 return GetElementsKind() == FAST_ELEMENTS;
4086}
4087
4088
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004089bool JSObject::HasFastSmiOnlyElements() {
4090 return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS;
4091}
4092
4093
4094bool JSObject::HasFastTypeElements() {
4095 ElementsKind elements_kind = GetElementsKind();
4096 return elements_kind == FAST_SMI_ONLY_ELEMENTS ||
4097 elements_kind == FAST_ELEMENTS;
4098}
4099
4100
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004101bool JSObject::HasFastDoubleElements() {
4102 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
4103}
4104
4105
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004106bool JSObject::HasDictionaryElements() {
4107 return GetElementsKind() == DICTIONARY_ELEMENTS;
4108}
4109
4110
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004111bool JSObject::HasNonStrictArgumentsElements() {
4112 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4113}
4114
4115
ager@chromium.org3811b432009-10-28 14:53:37 +00004116bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004117 HeapObject* array = elements();
4118 ASSERT(array != NULL);
4119 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004120}
4121
4122
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004123#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4124bool JSObject::HasExternal##name##Elements() { \
4125 HeapObject* array = elements(); \
4126 ASSERT(array != NULL); \
4127 if (!array->IsHeapObject()) \
4128 return false; \
4129 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004130}
4131
4132
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004133EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4134EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4135EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4136EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4137 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4138EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4139EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4140 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4141EXTERNAL_ELEMENTS_CHECK(Float,
4142 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004143EXTERNAL_ELEMENTS_CHECK(Double,
4144 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004145EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004146
4147
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004148bool JSObject::HasNamedInterceptor() {
4149 return map()->has_named_interceptor();
4150}
4151
4152
4153bool JSObject::HasIndexedInterceptor() {
4154 return map()->has_indexed_interceptor();
4155}
4156
4157
ager@chromium.org5c838252010-02-19 08:53:10 +00004158bool JSObject::AllowsSetElementsLength() {
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004159 bool result = elements()->IsFixedArray() ||
4160 elements()->IsFixedDoubleArray();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004161 ASSERT(result == !HasExternalArrayElements());
ager@chromium.org5c838252010-02-19 08:53:10 +00004162 return result;
4163}
4164
4165
lrn@chromium.org303ada72010-10-27 09:33:13 +00004166MaybeObject* JSObject::EnsureWritableFastElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004167 ASSERT(HasFastTypeElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004168 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004169 Isolate* isolate = GetIsolate();
4170 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004171 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004172 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4173 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004174 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4175 return maybe_writable_elems;
4176 }
4177 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004178 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004179 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004180 return writable_elems;
4181}
4182
4183
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004184StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004185 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004186 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004187}
4188
4189
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004190NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004191 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004192 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004193}
4194
4195
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004196bool String::IsHashFieldComputed(uint32_t field) {
4197 return (field & kHashNotComputedMask) == 0;
4198}
4199
4200
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004201bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004202 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004203}
4204
4205
4206uint32_t String::Hash() {
4207 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004208 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004209 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004210 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004211 return ComputeAndSetHash();
4212}
4213
4214
ager@chromium.org7c537e22008-10-16 08:43:32 +00004215StringHasher::StringHasher(int length)
4216 : length_(length),
4217 raw_running_hash_(0),
4218 array_index_(0),
4219 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4220 is_first_char_(true),
4221 is_valid_(true) { }
4222
4223
4224bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004225 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004226}
4227
4228
4229void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004230 // Use the Jenkins one-at-a-time hash function to update the hash
4231 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004232 raw_running_hash_ += c;
4233 raw_running_hash_ += (raw_running_hash_ << 10);
4234 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004235 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004236 if (is_array_index_) {
4237 if (c < '0' || c > '9') {
4238 is_array_index_ = false;
4239 } else {
4240 int d = c - '0';
4241 if (is_first_char_) {
4242 is_first_char_ = false;
4243 if (c == '0' && length_ > 1) {
4244 is_array_index_ = false;
4245 return;
4246 }
4247 }
4248 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4249 is_array_index_ = false;
4250 } else {
4251 array_index_ = array_index_ * 10 + d;
4252 }
4253 }
4254 }
4255}
4256
4257
4258void StringHasher::AddCharacterNoIndex(uc32 c) {
4259 ASSERT(!is_array_index());
4260 raw_running_hash_ += c;
4261 raw_running_hash_ += (raw_running_hash_ << 10);
4262 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4263}
4264
4265
4266uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004267 // Get the calculated raw hash value and do some more bit ops to distribute
4268 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004269 uint32_t result = raw_running_hash_;
4270 result += (result << 3);
4271 result ^= (result >> 11);
4272 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004273 if (result == 0) {
4274 result = 27;
4275 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004276 return result;
4277}
4278
4279
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004280template <typename schar>
4281uint32_t HashSequentialString(const schar* chars, int length) {
4282 StringHasher hasher(length);
4283 if (!hasher.has_trivial_hash()) {
4284 int i;
4285 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4286 hasher.AddCharacter(chars[i]);
4287 }
4288 for (; i < length; i++) {
4289 hasher.AddCharacterNoIndex(chars[i]);
4290 }
4291 }
4292 return hasher.GetHashField();
4293}
4294
4295
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004296bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004297 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004298 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4299 return false;
4300 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004301 return SlowAsArrayIndex(index);
4302}
4303
4304
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004305Object* JSReceiver::GetPrototype() {
4306 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004307}
4308
4309
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004310bool JSReceiver::HasProperty(String* name) {
4311 if (IsJSProxy()) {
4312 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4313 }
4314 return GetPropertyAttribute(name) != ABSENT;
4315}
4316
4317
4318bool JSReceiver::HasLocalProperty(String* name) {
4319 if (IsJSProxy()) {
4320 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4321 }
4322 return GetLocalPropertyAttribute(name) != ABSENT;
4323}
4324
4325
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004326PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004327 return GetPropertyAttributeWithReceiver(this, key);
4328}
4329
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004330// TODO(504): this may be useful in other places too where JSGlobalProxy
4331// is used.
4332Object* JSObject::BypassGlobalProxy() {
4333 if (IsJSGlobalProxy()) {
4334 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004335 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004336 ASSERT(proto->IsJSGlobalObject());
4337 return proto;
4338 }
4339 return this;
4340}
4341
4342
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004343MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4344 return IsJSProxy()
4345 ? JSProxy::cast(this)->GetIdentityHash(flag)
4346 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004347}
4348
4349
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004350bool JSReceiver::HasElement(uint32_t index) {
4351 if (IsJSProxy()) {
4352 return JSProxy::cast(this)->HasElementWithHandler(index);
4353 }
4354 return JSObject::cast(this)->HasElementWithReceiver(this, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004355}
4356
4357
4358bool AccessorInfo::all_can_read() {
4359 return BooleanBit::get(flag(), kAllCanReadBit);
4360}
4361
4362
4363void AccessorInfo::set_all_can_read(bool value) {
4364 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4365}
4366
4367
4368bool AccessorInfo::all_can_write() {
4369 return BooleanBit::get(flag(), kAllCanWriteBit);
4370}
4371
4372
4373void AccessorInfo::set_all_can_write(bool value) {
4374 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4375}
4376
4377
ager@chromium.org870a0b62008-11-04 11:43:05 +00004378bool AccessorInfo::prohibits_overwriting() {
4379 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4380}
4381
4382
4383void AccessorInfo::set_prohibits_overwriting(bool value) {
4384 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4385}
4386
4387
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004388PropertyAttributes AccessorInfo::property_attributes() {
4389 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4390}
4391
4392
4393void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004394 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004395}
4396
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004397
4398template<typename Shape, typename Key>
4399void Dictionary<Shape, Key>::SetEntry(int entry,
4400 Object* key,
4401 Object* value) {
4402 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4403}
4404
4405
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004406template<typename Shape, typename Key>
4407void Dictionary<Shape, Key>::SetEntry(int entry,
4408 Object* key,
4409 Object* value,
4410 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004411 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004412 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004413 AssertNoAllocation no_gc;
4414 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004415 FixedArray::set(index, key, mode);
4416 FixedArray::set(index+1, value, mode);
4417 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004418}
4419
4420
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004421bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4422 ASSERT(other->IsNumber());
4423 return key == static_cast<uint32_t>(other->Number());
4424}
4425
4426
4427uint32_t NumberDictionaryShape::Hash(uint32_t key) {
4428 return ComputeIntegerHash(key);
4429}
4430
4431
4432uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
4433 ASSERT(other->IsNumber());
4434 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
4435}
4436
4437
4438MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4439 return Isolate::Current()->heap()->NumberFromUint32(key);
4440}
4441
4442
4443bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4444 // We know that all entries in a hash table had their hash keys created.
4445 // Use that knowledge to have fast failure.
4446 if (key->Hash() != String::cast(other)->Hash()) return false;
4447 return key->Equals(String::cast(other));
4448}
4449
4450
4451uint32_t StringDictionaryShape::Hash(String* key) {
4452 return key->Hash();
4453}
4454
4455
4456uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4457 return String::cast(other)->Hash();
4458}
4459
4460
4461MaybeObject* StringDictionaryShape::AsObject(String* key) {
4462 return key;
4463}
4464
4465
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004466bool ObjectHashTableShape::IsMatch(JSReceiver* key, Object* other) {
4467 return key == JSReceiver::cast(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004468}
4469
4470
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004471uint32_t ObjectHashTableShape::Hash(JSReceiver* key) {
4472 MaybeObject* maybe_hash = key->GetIdentityHash(OMIT_CREATION);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004473 ASSERT(!maybe_hash->IsFailure());
4474 return Smi::cast(maybe_hash->ToObjectUnchecked())->value();
4475}
4476
4477
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004478uint32_t ObjectHashTableShape::HashForObject(JSReceiver* key, Object* other) {
4479 MaybeObject* maybe_hash =
4480 JSReceiver::cast(other)->GetIdentityHash(OMIT_CREATION);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004481 ASSERT(!maybe_hash->IsFailure());
4482 return Smi::cast(maybe_hash->ToObjectUnchecked())->value();
4483}
4484
4485
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004486MaybeObject* ObjectHashTableShape::AsObject(JSReceiver* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004487 return key;
4488}
4489
4490
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004491void ObjectHashTable::RemoveEntry(int entry) {
4492 RemoveEntry(entry, GetHeap());
4493}
4494
4495
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004496void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004497 // No write barrier is needed since empty_fixed_array is not in new space.
4498 // Please note this function is used during marking:
4499 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004500 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4501 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004502}
4503
4504
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004505void JSArray::EnsureSize(int required_size) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004506 ASSERT(HasFastTypeElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004507 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004508 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4509 if (elts->length() < required_size) {
4510 // Doubling in size would be overkill, but leave some slack to avoid
4511 // constantly growing.
4512 Expand(required_size + (required_size >> 3));
4513 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004514 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004515 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4516 // Expand will allocate a new backing store in new space even if the size
4517 // we asked for isn't larger than what we had before.
4518 Expand(required_size);
4519 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004520}
4521
4522
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004523void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004524 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004525 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4526}
4527
4528
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004529MaybeObject* JSArray::SetContent(FixedArray* storage) {
4530 MaybeObject* maybe_object = EnsureCanContainElements(storage);
4531 if (maybe_object->IsFailure()) return maybe_object;
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004532 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004533 set_elements(storage);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004534 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004535}
4536
4537
lrn@chromium.org303ada72010-10-27 09:33:13 +00004538MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004539 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004540 return GetHeap()->CopyFixedArray(this);
4541}
4542
4543
4544Relocatable::Relocatable(Isolate* isolate) {
4545 ASSERT(isolate == Isolate::Current());
4546 isolate_ = isolate;
4547 prev_ = isolate->relocatable_top();
4548 isolate->set_relocatable_top(this);
4549}
4550
4551
4552Relocatable::~Relocatable() {
4553 ASSERT(isolate_ == Isolate::Current());
4554 ASSERT_EQ(isolate_->relocatable_top(), this);
4555 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004556}
4557
4558
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004559int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4560 return map->instance_size();
4561}
4562
4563
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004564void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004565 v->VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004566 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004567}
4568
4569
4570template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004571void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004572 StaticVisitor::VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004573 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004574}
4575
4576
4577void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4578 typedef v8::String::ExternalAsciiStringResource Resource;
4579 v->VisitExternalAsciiString(
4580 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4581}
4582
4583
4584template<typename StaticVisitor>
4585void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4586 typedef v8::String::ExternalAsciiStringResource Resource;
4587 StaticVisitor::VisitExternalAsciiString(
4588 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4589}
4590
4591
4592void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4593 typedef v8::String::ExternalStringResource Resource;
4594 v->VisitExternalTwoByteString(
4595 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4596}
4597
4598
4599template<typename StaticVisitor>
4600void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4601 typedef v8::String::ExternalStringResource Resource;
4602 StaticVisitor::VisitExternalTwoByteString(
4603 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4604}
4605
4606#define SLOT_ADDR(obj, offset) \
4607 reinterpret_cast<Object**>((obj)->address() + offset)
4608
4609template<int start_offset, int end_offset, int size>
4610void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4611 HeapObject* obj,
4612 ObjectVisitor* v) {
4613 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4614}
4615
4616
4617template<int start_offset>
4618void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4619 int object_size,
4620 ObjectVisitor* v) {
4621 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4622}
4623
4624#undef SLOT_ADDR
4625
4626
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004627#undef CAST_ACCESSOR
4628#undef INT_ACCESSORS
4629#undef SMI_ACCESSORS
4630#undef ACCESSORS
4631#undef FIELD_ADDR
4632#undef READ_FIELD
4633#undef WRITE_FIELD
4634#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004635#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004636#undef READ_MEMADDR_FIELD
4637#undef WRITE_MEMADDR_FIELD
4638#undef READ_DOUBLE_FIELD
4639#undef WRITE_DOUBLE_FIELD
4640#undef READ_INT_FIELD
4641#undef WRITE_INT_FIELD
4642#undef READ_SHORT_FIELD
4643#undef WRITE_SHORT_FIELD
4644#undef READ_BYTE_FIELD
4645#undef WRITE_BYTE_FIELD
4646
4647
4648} } // namespace v8::internal
4649
4650#endif // V8_OBJECTS_INL_H_