blob: cebf9be074b3ec0458a523754de240e174a2fcde [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
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00001309 if (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001310 Heap* heap = GetHeap();
1311 // Don't use elements, since integrity checks will fail if there
1312 // are filler pointers in the array.
1313 FixedArray* fixed_array =
1314 reinterpret_cast<FixedArray*>(READ_FIELD(this, kElementsOffset));
1315 Map* map = fixed_array->map();
1316 // Arrays that have been shifted in place can't be verified.
1317 if (map != heap->raw_unchecked_one_pointer_filler_map() &&
1318 map != heap->raw_unchecked_two_pointer_filler_map() &&
1319 map != heap->free_space_map()) {
1320 for (int i = 0; i < fixed_array->length(); i++) {
1321 Object* current = fixed_array->get(i);
1322 ASSERT(current->IsSmi() || current == heap->the_hole_value());
1323 }
1324 }
1325 }
1326#endif
1327}
1328
1329
1330MaybeObject* JSObject::EnsureCanContainNonSmiElements() {
1331#if DEBUG
1332 ValidateSmiOnlyElements();
1333#endif
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00001334 if ((map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS)) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001335 Object* obj;
1336 MaybeObject* maybe_obj = GetElementsTransitionMap(FAST_ELEMENTS);
1337 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1338 set_map(Map::cast(obj));
1339 }
1340 return this;
1341}
1342
1343
1344MaybeObject* JSObject::EnsureCanContainElements(Object** objects,
1345 uint32_t count) {
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00001346 if (map()->elements_kind() == FAST_SMI_ONLY_ELEMENTS) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001347 for (uint32_t i = 0; i < count; ++i) {
1348 Object* current = *objects++;
1349 if (!current->IsSmi() && current != GetHeap()->the_hole_value()) {
1350 return EnsureCanContainNonSmiElements();
1351 }
1352 }
1353 }
1354 return this;
1355}
1356
1357
1358MaybeObject* JSObject::EnsureCanContainElements(FixedArray* elements) {
svenpanne@chromium.orga8bb4d92011-10-10 13:20:40 +00001359 Object** objects = reinterpret_cast<Object**>(
1360 FIELD_ADDR(elements, elements->OffsetOfElementAt(0)));
1361 return EnsureCanContainElements(objects, elements->length());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001362}
1363
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001364
whesse@chromium.org4acdc2c2011-08-15 13:01:23 +00001365void JSObject::set_elements(FixedArrayBase* value, WriteBarrierMode mode) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001366 ASSERT((map()->has_fast_elements() ||
1367 map()->has_fast_smi_only_elements()) ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001368 (value->map() == GetHeap()->fixed_array_map() ||
1369 value->map() == GetHeap()->fixed_cow_array_map()));
lrn@chromium.orgd4e9e222011-08-03 12:01:58 +00001370 ASSERT(map()->has_fast_double_elements() ==
1371 value->IsFixedDoubleArray());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001372 ASSERT(value->HasValidElements());
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001373#ifdef DEBUG
1374 ValidateSmiOnlyElements();
1375#endif
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001376 WRITE_FIELD(this, kElementsOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001377 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, value, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001378}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001379
1380
1381void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001382 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1383 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001384}
1385
1386
1387void JSObject::initialize_elements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001388 ASSERT(map()->has_fast_elements() || map()->has_fast_smi_only_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001389 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1390 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001391}
1392
1393
lrn@chromium.org303ada72010-10-27 09:33:13 +00001394MaybeObject* JSObject::ResetElements() {
1395 Object* obj;
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001396 ElementsKind elements_kind = FLAG_smi_only_arrays
1397 ? FAST_SMI_ONLY_ELEMENTS
1398 : FAST_ELEMENTS;
1399 MaybeObject* maybe_obj = GetElementsTransitionMap(elements_kind);
1400 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001401 set_map(Map::cast(obj));
1402 initialize_elements();
1403 return this;
1404}
1405
1406
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001407ACCESSORS(Oddball, to_string, String, kToStringOffset)
1408ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1409
1410
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001411byte Oddball::kind() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001412 return Smi::cast(READ_FIELD(this, kKindOffset))->value();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001413}
1414
1415
1416void Oddball::set_kind(byte value) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001417 WRITE_FIELD(this, kKindOffset, Smi::FromInt(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001418}
1419
1420
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001421Object* JSGlobalPropertyCell::value() {
1422 return READ_FIELD(this, kValueOffset);
1423}
1424
1425
1426void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1427 // The write barrier is not used for global property cells.
1428 ASSERT(!val->IsJSGlobalPropertyCell());
1429 WRITE_FIELD(this, kValueOffset, val);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001430 GetHeap()->incremental_marking()->RecordWrite(
1431 this, HeapObject::RawField(this, kValueOffset), val);
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001432}
1433
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001434
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001435int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001436 InstanceType type = map()->instance_type();
1437 // Check for the most common kind of JavaScript object before
1438 // falling into the generic switch. This speeds up the internal
1439 // field operations considerably on average.
1440 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1441 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001442 case JS_GLOBAL_PROXY_TYPE:
1443 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001444 case JS_GLOBAL_OBJECT_TYPE:
1445 return JSGlobalObject::kSize;
1446 case JS_BUILTINS_OBJECT_TYPE:
1447 return JSBuiltinsObject::kSize;
1448 case JS_FUNCTION_TYPE:
1449 return JSFunction::kSize;
1450 case JS_VALUE_TYPE:
1451 return JSValue::kSize;
1452 case JS_ARRAY_TYPE:
1453 return JSValue::kSize;
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001454 case JS_WEAK_MAP_TYPE:
1455 return JSWeakMap::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001456 case JS_REGEXP_TYPE:
1457 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001458 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001459 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001460 case JS_MESSAGE_OBJECT_TYPE:
1461 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001462 default:
1463 UNREACHABLE();
1464 return 0;
1465 }
1466}
1467
1468
1469int JSObject::GetInternalFieldCount() {
1470 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001471 // Make sure to adjust for the number of in-object properties. These
1472 // properties do contribute to the size, but are not internal fields.
1473 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1474 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001475}
1476
1477
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001478int JSObject::GetInternalFieldOffset(int index) {
1479 ASSERT(index < GetInternalFieldCount() && index >= 0);
1480 return GetHeaderSize() + (kPointerSize * index);
1481}
1482
1483
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001484Object* JSObject::GetInternalField(int index) {
1485 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001486 // Internal objects do follow immediately after the header, whereas in-object
1487 // properties are at the end of the object. Therefore there is no need
1488 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001489 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1490}
1491
1492
1493void JSObject::SetInternalField(int index, Object* value) {
1494 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001495 // Internal objects do follow immediately after the header, whereas in-object
1496 // properties are at the end of the object. Therefore there is no need
1497 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001498 int offset = GetHeaderSize() + (kPointerSize * index);
1499 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001500 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001501}
1502
1503
ager@chromium.org7c537e22008-10-16 08:43:32 +00001504// Access fast-case object properties at index. The use of these routines
1505// is needed to correctly distinguish between properties stored in-object and
1506// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001507Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001508 // Adjust for the number of properties stored in the object.
1509 index -= map()->inobject_properties();
1510 if (index < 0) {
1511 int offset = map()->instance_size() + (index * kPointerSize);
1512 return READ_FIELD(this, offset);
1513 } else {
1514 ASSERT(index < properties()->length());
1515 return properties()->get(index);
1516 }
1517}
1518
1519
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001520Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001521 // Adjust for the number of properties stored in the object.
1522 index -= map()->inobject_properties();
1523 if (index < 0) {
1524 int offset = map()->instance_size() + (index * kPointerSize);
1525 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001526 WRITE_BARRIER(GetHeap(), this, offset, value);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001527 } else {
1528 ASSERT(index < properties()->length());
1529 properties()->set(index, value);
1530 }
1531 return value;
1532}
1533
1534
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001535int JSObject::GetInObjectPropertyOffset(int index) {
1536 // Adjust for the number of properties stored in the object.
1537 index -= map()->inobject_properties();
1538 ASSERT(index < 0);
1539 return map()->instance_size() + (index * kPointerSize);
1540}
1541
1542
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001543Object* JSObject::InObjectPropertyAt(int index) {
1544 // Adjust for the number of properties stored in the object.
1545 index -= map()->inobject_properties();
1546 ASSERT(index < 0);
1547 int offset = map()->instance_size() + (index * kPointerSize);
1548 return READ_FIELD(this, offset);
1549}
1550
1551
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001552Object* JSObject::InObjectPropertyAtPut(int index,
1553 Object* value,
1554 WriteBarrierMode mode) {
1555 // Adjust for the number of properties stored in the object.
1556 index -= map()->inobject_properties();
1557 ASSERT(index < 0);
1558 int offset = map()->instance_size() + (index * kPointerSize);
1559 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001560 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001561 return value;
1562}
1563
1564
1565
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001566void JSObject::InitializeBody(Map* map,
1567 Object* pre_allocated_value,
1568 Object* filler_value) {
1569 ASSERT(!filler_value->IsHeapObject() ||
1570 !GetHeap()->InNewSpace(filler_value));
1571 ASSERT(!pre_allocated_value->IsHeapObject() ||
1572 !GetHeap()->InNewSpace(pre_allocated_value));
1573 int size = map->instance_size();
1574 int offset = kHeaderSize;
1575 if (filler_value != pre_allocated_value) {
1576 int pre_allocated = map->pre_allocated_property_fields();
1577 ASSERT(pre_allocated * kPointerSize + kHeaderSize <= size);
1578 for (int i = 0; i < pre_allocated; i++) {
1579 WRITE_FIELD(this, offset, pre_allocated_value);
1580 offset += kPointerSize;
1581 }
1582 }
1583 while (offset < size) {
1584 WRITE_FIELD(this, offset, filler_value);
1585 offset += kPointerSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001586 }
1587}
1588
1589
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001590bool JSObject::HasFastProperties() {
1591 return !properties()->IsDictionary();
1592}
1593
1594
1595int JSObject::MaxFastProperties() {
1596 // Allow extra fast properties if the object has more than
1597 // kMaxFastProperties in-object properties. When this is the case,
1598 // it is very unlikely that the object is being used as a dictionary
1599 // and there is a good chance that allowing more map transitions
1600 // will be worth it.
1601 return Max(map()->inobject_properties(), kMaxFastProperties);
1602}
1603
1604
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001605void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001606 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001607 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001608 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001609 }
1610}
1611
1612
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001613bool Object::ToArrayIndex(uint32_t* index) {
1614 if (IsSmi()) {
1615 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001616 if (value < 0) return false;
1617 *index = value;
1618 return true;
1619 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001620 if (IsHeapNumber()) {
1621 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001622 uint32_t uint_value = static_cast<uint32_t>(value);
1623 if (value == static_cast<double>(uint_value)) {
1624 *index = uint_value;
1625 return true;
1626 }
1627 }
1628 return false;
1629}
1630
1631
1632bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1633 if (!this->IsJSValue()) return false;
1634
1635 JSValue* js_value = JSValue::cast(this);
1636 if (!js_value->value()->IsString()) return false;
1637
1638 String* str = String::cast(js_value->value());
1639 if (index >= (uint32_t)str->length()) return false;
1640
1641 return true;
1642}
1643
1644
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001645FixedArrayBase* FixedArrayBase::cast(Object* object) {
1646 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1647 return reinterpret_cast<FixedArrayBase*>(object);
1648}
1649
1650
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001651Object* FixedArray::get(int index) {
1652 ASSERT(index >= 0 && index < this->length());
1653 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1654}
1655
1656
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001657void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001658 ASSERT(map() != HEAP->fixed_cow_array_map());
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001659 ASSERT(index >= 0 && index < this->length());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001660 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1661 int offset = kHeaderSize + index * kPointerSize;
1662 WRITE_FIELD(this, offset, value);
1663}
1664
1665
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001666void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001667 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001668 ASSERT(index >= 0 && index < this->length());
1669 int offset = kHeaderSize + index * kPointerSize;
1670 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001671 WRITE_BARRIER(GetHeap(), this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001672}
1673
1674
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001675inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1676 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1677}
1678
1679
1680inline double FixedDoubleArray::hole_nan_as_double() {
1681 return BitCast<double, uint64_t>(kHoleNanInt64);
1682}
1683
1684
1685inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1686 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1687 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1688 return OS::nan_value();
1689}
1690
1691
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001692double FixedDoubleArray::get_scalar(int index) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001693 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1694 map() != HEAP->fixed_array_map());
1695 ASSERT(index >= 0 && index < this->length());
1696 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1697 ASSERT(!is_the_hole_nan(result));
1698 return result;
1699}
1700
1701
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00001702MaybeObject* FixedDoubleArray::get(int index) {
1703 if (is_the_hole(index)) {
1704 return GetHeap()->the_hole_value();
1705 } else {
1706 return GetHeap()->NumberFromDouble(get_scalar(index));
1707 }
1708}
1709
1710
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001711void FixedDoubleArray::set(int index, double value) {
1712 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1713 map() != HEAP->fixed_array_map());
1714 int offset = kHeaderSize + index * kDoubleSize;
1715 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1716 WRITE_DOUBLE_FIELD(this, offset, value);
1717}
1718
1719
1720void FixedDoubleArray::set_the_hole(int index) {
1721 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1722 map() != HEAP->fixed_array_map());
1723 int offset = kHeaderSize + index * kDoubleSize;
1724 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1725}
1726
1727
1728bool FixedDoubleArray::is_the_hole(int index) {
1729 int offset = kHeaderSize + index * kDoubleSize;
1730 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1731}
1732
1733
1734void FixedDoubleArray::Initialize(FixedDoubleArray* from) {
1735 int old_length = from->length();
1736 ASSERT(old_length < length());
jkummerow@chromium.org486075a2011-09-07 12:44:28 +00001737 if (old_length * kDoubleSize >= OS::kMinComplexMemCopy) {
1738 OS::MemCopy(FIELD_ADDR(this, kHeaderSize),
1739 FIELD_ADDR(from, kHeaderSize),
1740 old_length * kDoubleSize);
1741 } else {
1742 for (int i = 0; i < old_length; ++i) {
1743 set(i, from->get_scalar(i));
1744 }
1745 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001746 int offset = kHeaderSize + old_length * kDoubleSize;
1747 for (int current = from->length(); current < length(); ++current) {
1748 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1749 offset += kDoubleSize;
1750 }
1751}
1752
1753
1754void FixedDoubleArray::Initialize(FixedArray* from) {
1755 int old_length = from->length();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001756 ASSERT(old_length <= length());
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001757 for (int i = 0; i < old_length; i++) {
1758 Object* hole_or_object = from->get(i);
1759 if (hole_or_object->IsTheHole()) {
1760 set_the_hole(i);
1761 } else {
1762 set(i, hole_or_object->Number());
1763 }
1764 }
1765 int offset = kHeaderSize + old_length * kDoubleSize;
1766 for (int current = from->length(); current < length(); ++current) {
1767 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1768 offset += kDoubleSize;
1769 }
1770}
1771
1772
1773void FixedDoubleArray::Initialize(NumberDictionary* from) {
1774 int offset = kHeaderSize;
1775 for (int current = 0; current < length(); ++current) {
1776 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1777 offset += kDoubleSize;
1778 }
1779 for (int i = 0; i < from->Capacity(); i++) {
1780 Object* key = from->KeyAt(i);
1781 if (key->IsNumber()) {
1782 uint32_t entry = static_cast<uint32_t>(key->Number());
1783 set(entry, from->ValueAt(i)->Number());
1784 }
1785 }
1786}
1787
1788
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001789WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001790 Heap* heap = GetHeap();
1791 if (heap->incremental_marking()->IsMarking()) return UPDATE_WRITE_BARRIER;
1792 if (heap->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001793 return UPDATE_WRITE_BARRIER;
1794}
1795
1796
1797void FixedArray::set(int index,
1798 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001799 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001800 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001801 ASSERT(index >= 0 && index < this->length());
1802 int offset = kHeaderSize + index * kPointerSize;
1803 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001804 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001805}
1806
1807
1808void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001809 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001810 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001811 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001812 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001813 array->GetHeap()->incremental_marking()->RecordWrite(
1814 array,
1815 HeapObject::RawField(array, kHeaderSize + index * kPointerSize),
1816 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001817}
1818
1819
1820void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001821 ASSERT(map() != HEAP->fixed_cow_array_map());
1822 set_undefined(GetHeap(), index);
1823}
1824
1825
1826void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001827 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001828 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001829 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001830 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001831}
1832
1833
ager@chromium.org236ad962008-09-25 09:45:57 +00001834void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001835 set_null(GetHeap(), index);
1836}
1837
1838
1839void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001840 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001841 ASSERT(!heap->InNewSpace(heap->null_value()));
1842 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001843}
1844
1845
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001846void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001847 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001848 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001849 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1850 WRITE_FIELD(this,
1851 kHeaderSize + index * kPointerSize,
1852 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001853}
1854
1855
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001856void FixedArray::set_unchecked(int index, Smi* value) {
1857 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1858 int offset = kHeaderSize + index * kPointerSize;
1859 WRITE_FIELD(this, offset, value);
1860}
1861
1862
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001863void FixedArray::set_unchecked(Heap* heap,
1864 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001865 Object* value,
1866 WriteBarrierMode mode) {
1867 int offset = kHeaderSize + index * kPointerSize;
1868 WRITE_FIELD(this, offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00001869 CONDITIONAL_WRITE_BARRIER(heap, this, offset, value, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001870}
1871
1872
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001873void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001874 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001875 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1876 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001877}
1878
1879
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001880Object** FixedArray::data_start() {
1881 return HeapObject::RawField(this, kHeaderSize);
1882}
1883
1884
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001885bool DescriptorArray::IsEmpty() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00001886 ASSERT(this->IsSmi() ||
1887 this->length() > kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001888 this == HEAP->empty_descriptor_array());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001889 return this->IsSmi() || length() <= kFirstIndex;
1890}
1891
1892
1893int DescriptorArray::bit_field3_storage() {
1894 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1895 return Smi::cast(storage)->value();
1896}
1897
1898void DescriptorArray::set_bit_field3_storage(int value) {
1899 ASSERT(!IsEmpty());
1900 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001901}
1902
1903
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001904void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1905 Object* tmp = array->get(first);
1906 fast_set(array, first, array->get(second));
1907 fast_set(array, second, tmp);
1908}
1909
1910
1911int DescriptorArray::Search(String* name) {
1912 SLOW_ASSERT(IsSortedNoDuplicates());
1913
1914 // Check for empty descriptor array.
1915 int nof = number_of_descriptors();
1916 if (nof == 0) return kNotFound;
1917
1918 // Fast case: do linear search for small arrays.
1919 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001920 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001921 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001922 }
1923
1924 // Slow case: perform binary search.
1925 return BinarySearch(name, 0, nof - 1);
1926}
1927
1928
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001929int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001930 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001931 if (number == DescriptorLookupCache::kAbsent) {
1932 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001933 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001934 }
1935 return number;
1936}
1937
1938
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001939String* DescriptorArray::GetKey(int descriptor_number) {
1940 ASSERT(descriptor_number < number_of_descriptors());
1941 return String::cast(get(ToKeyIndex(descriptor_number)));
1942}
1943
1944
1945Object* DescriptorArray::GetValue(int descriptor_number) {
1946 ASSERT(descriptor_number < number_of_descriptors());
1947 return GetContentArray()->get(ToValueIndex(descriptor_number));
1948}
1949
1950
1951Smi* DescriptorArray::GetDetails(int descriptor_number) {
1952 ASSERT(descriptor_number < number_of_descriptors());
1953 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1954}
1955
1956
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001957PropertyType DescriptorArray::GetType(int descriptor_number) {
1958 ASSERT(descriptor_number < number_of_descriptors());
1959 return PropertyDetails(GetDetails(descriptor_number)).type();
1960}
1961
1962
1963int DescriptorArray::GetFieldIndex(int descriptor_number) {
1964 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1965}
1966
1967
1968JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1969 return JSFunction::cast(GetValue(descriptor_number));
1970}
1971
1972
1973Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1974 ASSERT(GetType(descriptor_number) == CALLBACKS);
1975 return GetValue(descriptor_number);
1976}
1977
1978
1979AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1980 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001981 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
1982 return reinterpret_cast<AccessorDescriptor*>(p->address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001983}
1984
1985
1986bool DescriptorArray::IsProperty(int descriptor_number) {
1987 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1988}
1989
1990
1991bool DescriptorArray::IsTransition(int descriptor_number) {
1992 PropertyType t = GetType(descriptor_number);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001993 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION ||
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00001994 t == ELEMENTS_TRANSITION;
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001995}
1996
1997
1998bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1999 return GetType(descriptor_number) == NULL_DESCRIPTOR;
2000}
2001
2002
2003bool DescriptorArray::IsDontEnum(int descriptor_number) {
2004 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
2005}
2006
2007
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002008void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
2009 desc->Init(GetKey(descriptor_number),
2010 GetValue(descriptor_number),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00002011 PropertyDetails(GetDetails(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002012}
2013
2014
2015void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
2016 // Range check.
2017 ASSERT(descriptor_number < number_of_descriptors());
2018
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00002019 // Make sure none of the elements in desc are in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002020 ASSERT(!HEAP->InNewSpace(desc->GetKey()));
2021 ASSERT(!HEAP->InNewSpace(desc->GetValue()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002022
2023 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
2024 FixedArray* content_array = GetContentArray();
2025 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
2026 fast_set(content_array, ToDetailsIndex(descriptor_number),
2027 desc->GetDetails().AsSmi());
2028}
2029
2030
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00002031void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
2032 Descriptor desc;
2033 src->Get(src_index, &desc);
2034 Set(index, &desc);
2035}
2036
2037
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002038void DescriptorArray::Swap(int first, int second) {
2039 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
2040 FixedArray* content_array = GetContentArray();
2041 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
2042 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
2043}
2044
2045
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002046template<typename Shape, typename Key>
ricow@chromium.org2c99e282011-07-28 09:15:17 +00002047int HashTable<Shape, Key>::ComputeCapacity(int at_least_space_for) {
2048 const int kMinCapacity = 32;
2049 int capacity = RoundUpToPowerOf2(at_least_space_for * 2);
2050 if (capacity < kMinCapacity) {
2051 capacity = kMinCapacity; // Guarantee min capacity.
2052 }
2053 return capacity;
2054}
2055
2056
2057template<typename Shape, typename Key>
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002058int HashTable<Shape, Key>::FindEntry(Key key) {
2059 return FindEntry(GetIsolate(), key);
2060}
2061
2062
2063// Find entry for key otherwise return kNotFound.
2064template<typename Shape, typename Key>
2065int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
2066 uint32_t capacity = Capacity();
2067 uint32_t entry = FirstProbe(Shape::Hash(key), capacity);
2068 uint32_t count = 1;
2069 // EnsureCapacity will guarantee the hash table is never full.
2070 while (true) {
2071 Object* element = KeyAt(entry);
2072 if (element == isolate->heap()->undefined_value()) break; // Empty entry.
2073 if (element != isolate->heap()->null_value() &&
2074 Shape::IsMatch(key, element)) return entry;
2075 entry = NextProbe(entry, count++, capacity);
2076 }
2077 return kNotFound;
2078}
2079
2080
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002081bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002082 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002083 if (!max_index_object->IsSmi()) return false;
2084 return 0 !=
2085 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
2086}
2087
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002088uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002089 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002090 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002091 if (!max_index_object->IsSmi()) return 0;
2092 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2093 return value >> kRequiresSlowElementsTagSize;
2094}
2095
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002096void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002097 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002098}
2099
2100
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002101// ------------------------------------
2102// Cast operations
2103
2104
2105CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002106CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002107CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002108CAST_ACCESSOR(DeoptimizationInputData)
2109CAST_ACCESSOR(DeoptimizationOutputData)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002110CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002111CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002112CAST_ACCESSOR(NormalizedMapCache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002113CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002114CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002115CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002116CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002117CAST_ACCESSOR(String)
2118CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002119CAST_ACCESSOR(SeqAsciiString)
2120CAST_ACCESSOR(SeqTwoByteString)
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002121CAST_ACCESSOR(SlicedString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002122CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002123CAST_ACCESSOR(ExternalString)
2124CAST_ACCESSOR(ExternalAsciiString)
2125CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002126CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002127CAST_ACCESSOR(JSObject)
2128CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002129CAST_ACCESSOR(HeapObject)
2130CAST_ACCESSOR(HeapNumber)
2131CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002132CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002133CAST_ACCESSOR(SharedFunctionInfo)
2134CAST_ACCESSOR(Map)
2135CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002136CAST_ACCESSOR(GlobalObject)
2137CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002138CAST_ACCESSOR(JSGlobalObject)
2139CAST_ACCESSOR(JSBuiltinsObject)
2140CAST_ACCESSOR(Code)
2141CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002142CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002143CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002144CAST_ACCESSOR(JSFunctionProxy)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002145CAST_ACCESSOR(JSWeakMap)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002146CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002147CAST_ACCESSOR(ByteArray)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002148CAST_ACCESSOR(FreeSpace)
ager@chromium.org3811b432009-10-28 14:53:37 +00002149CAST_ACCESSOR(ExternalArray)
2150CAST_ACCESSOR(ExternalByteArray)
2151CAST_ACCESSOR(ExternalUnsignedByteArray)
2152CAST_ACCESSOR(ExternalShortArray)
2153CAST_ACCESSOR(ExternalUnsignedShortArray)
2154CAST_ACCESSOR(ExternalIntArray)
2155CAST_ACCESSOR(ExternalUnsignedIntArray)
2156CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002157CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002158CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002159CAST_ACCESSOR(Struct)
2160
2161
2162#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2163 STRUCT_LIST(MAKE_STRUCT_CAST)
2164#undef MAKE_STRUCT_CAST
2165
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002166
2167template <typename Shape, typename Key>
2168HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002169 ASSERT(obj->IsHashTable());
2170 return reinterpret_cast<HashTable*>(obj);
2171}
2172
2173
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002174SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002175SMI_ACCESSORS(FreeSpace, size, kSizeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002176
ager@chromium.orgac091b72010-05-05 07:34:42 +00002177SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002178
2179
2180uint32_t String::hash_field() {
2181 return READ_UINT32_FIELD(this, kHashFieldOffset);
2182}
2183
2184
2185void String::set_hash_field(uint32_t value) {
2186 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002187#if V8_HOST_ARCH_64_BIT
2188 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2189#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002190}
2191
2192
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002193bool String::Equals(String* other) {
2194 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002195 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2196 return false;
2197 }
2198 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002199}
2200
2201
lrn@chromium.org303ada72010-10-27 09:33:13 +00002202MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002203 if (!StringShape(this).IsCons()) return this;
2204 ConsString* cons = ConsString::cast(this);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002205 if (cons->IsFlat()) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002206 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002207}
2208
2209
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002210String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002211 MaybeObject* flat = TryFlatten(pretenure);
2212 Object* successfully_flattened;
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002213 if (!flat->ToObject(&successfully_flattened)) return this;
2214 return String::cast(successfully_flattened);
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002215}
2216
2217
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002218uint16_t String::Get(int index) {
2219 ASSERT(index >= 0 && index < length());
2220 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002221 case kSeqStringTag | kAsciiStringTag:
2222 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2223 case kSeqStringTag | kTwoByteStringTag:
2224 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2225 case kConsStringTag | kAsciiStringTag:
2226 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002227 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002228 case kExternalStringTag | kAsciiStringTag:
2229 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2230 case kExternalStringTag | kTwoByteStringTag:
2231 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002232 case kSlicedStringTag | kAsciiStringTag:
2233 case kSlicedStringTag | kTwoByteStringTag:
2234 return SlicedString::cast(this)->SlicedStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002235 default:
2236 break;
2237 }
2238
2239 UNREACHABLE();
2240 return 0;
2241}
2242
2243
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002244void String::Set(int index, uint16_t value) {
2245 ASSERT(index >= 0 && index < length());
2246 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002247
ager@chromium.org5ec48922009-05-05 07:25:34 +00002248 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002249 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2250 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002251}
2252
2253
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002254bool String::IsFlat() {
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002255 if (!StringShape(this).IsCons()) return true;
2256 return ConsString::cast(this)->second()->length() == 0;
2257}
2258
2259
2260String* String::GetUnderlying() {
2261 // Giving direct access to underlying string only makes sense if the
2262 // wrapping string is already flattened.
2263 ASSERT(this->IsFlat());
2264 ASSERT(StringShape(this).IsIndirect());
2265 STATIC_ASSERT(ConsString::kFirstOffset == SlicedString::kParentOffset);
2266 const int kUnderlyingOffset = SlicedString::kParentOffset;
2267 return String::cast(READ_FIELD(this, kUnderlyingOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002268}
2269
2270
ager@chromium.org7c537e22008-10-16 08:43:32 +00002271uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002272 ASSERT(index >= 0 && index < length());
2273 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2274}
2275
2276
ager@chromium.org7c537e22008-10-16 08:43:32 +00002277void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002278 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2279 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2280 static_cast<byte>(value));
2281}
2282
2283
ager@chromium.org7c537e22008-10-16 08:43:32 +00002284Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002285 return FIELD_ADDR(this, kHeaderSize);
2286}
2287
2288
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002289char* SeqAsciiString::GetChars() {
2290 return reinterpret_cast<char*>(GetCharsAddress());
2291}
2292
2293
ager@chromium.org7c537e22008-10-16 08:43:32 +00002294Address SeqTwoByteString::GetCharsAddress() {
2295 return FIELD_ADDR(this, kHeaderSize);
2296}
2297
2298
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002299uc16* SeqTwoByteString::GetChars() {
2300 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2301}
2302
2303
ager@chromium.org7c537e22008-10-16 08:43:32 +00002304uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002305 ASSERT(index >= 0 && index < length());
2306 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2307}
2308
2309
ager@chromium.org7c537e22008-10-16 08:43:32 +00002310void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002311 ASSERT(index >= 0 && index < length());
2312 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2313}
2314
2315
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002316int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002317 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002318}
2319
2320
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002321int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002322 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002323}
2324
2325
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002326String* SlicedString::parent() {
2327 return String::cast(READ_FIELD(this, kParentOffset));
2328}
2329
2330
2331void SlicedString::set_parent(String* parent) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002332 ASSERT(parent->IsSeqString() || parent->IsExternalString());
ricow@chromium.org4668a2c2011-08-29 10:41:00 +00002333 WRITE_FIELD(this, kParentOffset, parent);
2334}
2335
2336
2337SMI_ACCESSORS(SlicedString, offset, kOffsetOffset)
2338
2339
ager@chromium.org870a0b62008-11-04 11:43:05 +00002340String* ConsString::first() {
2341 return String::cast(READ_FIELD(this, kFirstOffset));
2342}
2343
2344
2345Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002346 return READ_FIELD(this, kFirstOffset);
2347}
2348
2349
ager@chromium.org870a0b62008-11-04 11:43:05 +00002350void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002351 WRITE_FIELD(this, kFirstOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002352 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002353}
2354
2355
ager@chromium.org870a0b62008-11-04 11:43:05 +00002356String* ConsString::second() {
2357 return String::cast(READ_FIELD(this, kSecondOffset));
2358}
2359
2360
2361Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002362 return READ_FIELD(this, kSecondOffset);
2363}
2364
2365
ager@chromium.org870a0b62008-11-04 11:43:05 +00002366void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002367 WRITE_FIELD(this, kSecondOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002368 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002369}
2370
2371
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002372const ExternalAsciiString::Resource* ExternalAsciiString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002373 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2374}
2375
2376
2377void ExternalAsciiString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002378 const ExternalAsciiString::Resource* resource) {
2379 *reinterpret_cast<const Resource**>(
2380 FIELD_ADDR(this, kResourceOffset)) = resource;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002381}
2382
2383
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002384const ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002385 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2386}
2387
2388
2389void ExternalTwoByteString::set_resource(
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002390 const ExternalTwoByteString::Resource* resource) {
2391 *reinterpret_cast<const Resource**>(
2392 FIELD_ADDR(this, kResourceOffset)) = resource;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002393}
2394
2395
ager@chromium.orgac091b72010-05-05 07:34:42 +00002396void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002397 set_finger_index(kEntriesIndex);
2398 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002399}
2400
2401
2402void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002403 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002404 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002405 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002406 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002407 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002408 MakeZeroSize();
2409}
2410
2411
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002412int JSFunctionResultCache::size() {
2413 return Smi::cast(get(kCacheSizeIndex))->value();
2414}
2415
2416
2417void JSFunctionResultCache::set_size(int size) {
2418 set(kCacheSizeIndex, Smi::FromInt(size));
2419}
2420
2421
2422int JSFunctionResultCache::finger_index() {
2423 return Smi::cast(get(kFingerIndex))->value();
2424}
2425
2426
2427void JSFunctionResultCache::set_finger_index(int finger_index) {
2428 set(kFingerIndex, Smi::FromInt(finger_index));
2429}
2430
2431
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002432byte ByteArray::get(int index) {
2433 ASSERT(index >= 0 && index < this->length());
2434 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2435}
2436
2437
2438void ByteArray::set(int index, byte value) {
2439 ASSERT(index >= 0 && index < this->length());
2440 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2441}
2442
2443
2444int ByteArray::get_int(int index) {
2445 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2446 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2447}
2448
2449
2450ByteArray* ByteArray::FromDataStartAddress(Address address) {
2451 ASSERT_TAG_ALIGNED(address);
2452 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2453}
2454
2455
2456Address ByteArray::GetDataStartAddress() {
2457 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2458}
2459
2460
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002461uint8_t* ExternalPixelArray::external_pixel_pointer() {
2462 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002463}
2464
2465
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002466uint8_t ExternalPixelArray::get_scalar(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002467 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002468 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002469 return ptr[index];
2470}
2471
2472
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002473MaybeObject* ExternalPixelArray::get(int index) {
2474 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2475}
2476
2477
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002478void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002479 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002480 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002481 ptr[index] = value;
2482}
2483
2484
ager@chromium.org3811b432009-10-28 14:53:37 +00002485void* ExternalArray::external_pointer() {
2486 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2487 return reinterpret_cast<void*>(ptr);
2488}
2489
2490
2491void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2492 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2493 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2494}
2495
2496
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002497int8_t ExternalByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002498 ASSERT((index >= 0) && (index < this->length()));
2499 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2500 return ptr[index];
2501}
2502
2503
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002504MaybeObject* ExternalByteArray::get(int index) {
2505 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2506}
2507
2508
ager@chromium.org3811b432009-10-28 14:53:37 +00002509void ExternalByteArray::set(int index, int8_t value) {
2510 ASSERT((index >= 0) && (index < this->length()));
2511 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2512 ptr[index] = value;
2513}
2514
2515
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002516uint8_t ExternalUnsignedByteArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002517 ASSERT((index >= 0) && (index < this->length()));
2518 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2519 return ptr[index];
2520}
2521
2522
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002523MaybeObject* ExternalUnsignedByteArray::get(int index) {
2524 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2525}
2526
2527
ager@chromium.org3811b432009-10-28 14:53:37 +00002528void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2529 ASSERT((index >= 0) && (index < this->length()));
2530 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2531 ptr[index] = value;
2532}
2533
2534
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002535int16_t ExternalShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002536 ASSERT((index >= 0) && (index < this->length()));
2537 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2538 return ptr[index];
2539}
2540
2541
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002542MaybeObject* ExternalShortArray::get(int index) {
2543 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2544}
2545
2546
ager@chromium.org3811b432009-10-28 14:53:37 +00002547void ExternalShortArray::set(int index, int16_t value) {
2548 ASSERT((index >= 0) && (index < this->length()));
2549 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2550 ptr[index] = value;
2551}
2552
2553
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002554uint16_t ExternalUnsignedShortArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002555 ASSERT((index >= 0) && (index < this->length()));
2556 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2557 return ptr[index];
2558}
2559
2560
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002561MaybeObject* ExternalUnsignedShortArray::get(int index) {
2562 return Smi::FromInt(static_cast<int>(get_scalar(index)));
2563}
2564
2565
ager@chromium.org3811b432009-10-28 14:53:37 +00002566void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2567 ASSERT((index >= 0) && (index < this->length()));
2568 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2569 ptr[index] = value;
2570}
2571
2572
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002573int32_t ExternalIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002574 ASSERT((index >= 0) && (index < this->length()));
2575 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2576 return ptr[index];
2577}
2578
2579
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002580MaybeObject* ExternalIntArray::get(int index) {
2581 return GetHeap()->NumberFromInt32(get_scalar(index));
2582}
2583
2584
ager@chromium.org3811b432009-10-28 14:53:37 +00002585void ExternalIntArray::set(int index, int32_t value) {
2586 ASSERT((index >= 0) && (index < this->length()));
2587 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2588 ptr[index] = value;
2589}
2590
2591
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002592uint32_t ExternalUnsignedIntArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002593 ASSERT((index >= 0) && (index < this->length()));
2594 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2595 return ptr[index];
2596}
2597
2598
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002599MaybeObject* ExternalUnsignedIntArray::get(int index) {
2600 return GetHeap()->NumberFromUint32(get_scalar(index));
2601}
2602
2603
ager@chromium.org3811b432009-10-28 14:53:37 +00002604void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2605 ASSERT((index >= 0) && (index < this->length()));
2606 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2607 ptr[index] = value;
2608}
2609
2610
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002611float ExternalFloatArray::get_scalar(int index) {
ager@chromium.org3811b432009-10-28 14:53:37 +00002612 ASSERT((index >= 0) && (index < this->length()));
2613 float* ptr = static_cast<float*>(external_pointer());
2614 return ptr[index];
2615}
2616
2617
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002618MaybeObject* ExternalFloatArray::get(int index) {
2619 return GetHeap()->NumberFromDouble(get_scalar(index));
2620}
2621
2622
ager@chromium.org3811b432009-10-28 14:53:37 +00002623void ExternalFloatArray::set(int index, float value) {
2624 ASSERT((index >= 0) && (index < this->length()));
2625 float* ptr = static_cast<float*>(external_pointer());
2626 ptr[index] = value;
2627}
2628
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002629
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002630double ExternalDoubleArray::get_scalar(int index) {
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002631 ASSERT((index >= 0) && (index < this->length()));
2632 double* ptr = static_cast<double*>(external_pointer());
2633 return ptr[index];
2634}
2635
2636
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00002637MaybeObject* ExternalDoubleArray::get(int index) {
2638 return GetHeap()->NumberFromDouble(get_scalar(index));
2639}
2640
2641
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002642void ExternalDoubleArray::set(int index, double value) {
2643 ASSERT((index >= 0) && (index < this->length()));
2644 double* ptr = static_cast<double*>(external_pointer());
2645 ptr[index] = value;
2646}
2647
2648
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002649int Map::visitor_id() {
2650 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2651}
2652
2653
2654void Map::set_visitor_id(int id) {
2655 ASSERT(0 <= id && id < 256);
2656 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2657}
2658
ager@chromium.org3811b432009-10-28 14:53:37 +00002659
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002660int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002661 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2662}
2663
2664
2665int Map::inobject_properties() {
2666 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002667}
2668
2669
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002670int Map::pre_allocated_property_fields() {
2671 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2672}
2673
2674
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002675int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002676 int instance_size = map->instance_size();
2677 if (instance_size != kVariableSizeSentinel) return instance_size;
2678 // We can ignore the "symbol" bit becase it is only set for symbols
2679 // and implies a string type.
2680 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002681 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002682 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002683 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002684 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002685 if (instance_type == ASCII_STRING_TYPE) {
2686 return SeqAsciiString::SizeFor(
2687 reinterpret_cast<SeqAsciiString*>(this)->length());
2688 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002689 if (instance_type == BYTE_ARRAY_TYPE) {
2690 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2691 }
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002692 if (instance_type == FREE_SPACE_TYPE) {
2693 return reinterpret_cast<FreeSpace*>(this)->size();
2694 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002695 if (instance_type == STRING_TYPE) {
2696 return SeqTwoByteString::SizeFor(
2697 reinterpret_cast<SeqTwoByteString*>(this)->length());
2698 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002699 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2700 return FixedDoubleArray::SizeFor(
2701 reinterpret_cast<FixedDoubleArray*>(this)->length());
2702 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002703 ASSERT(instance_type == CODE_TYPE);
2704 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002705}
2706
2707
2708void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002709 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002710 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002711 ASSERT(0 <= value && value < 256);
2712 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2713}
2714
2715
ager@chromium.org7c537e22008-10-16 08:43:32 +00002716void Map::set_inobject_properties(int value) {
2717 ASSERT(0 <= value && value < 256);
2718 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2719}
2720
2721
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002722void Map::set_pre_allocated_property_fields(int value) {
2723 ASSERT(0 <= value && value < 256);
2724 WRITE_BYTE_FIELD(this,
2725 kPreAllocatedPropertyFieldsOffset,
2726 static_cast<byte>(value));
2727}
2728
2729
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002730InstanceType Map::instance_type() {
2731 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2732}
2733
2734
2735void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002736 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2737}
2738
2739
2740int Map::unused_property_fields() {
2741 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2742}
2743
2744
2745void Map::set_unused_property_fields(int value) {
2746 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2747}
2748
2749
2750byte Map::bit_field() {
2751 return READ_BYTE_FIELD(this, kBitFieldOffset);
2752}
2753
2754
2755void Map::set_bit_field(byte value) {
2756 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2757}
2758
2759
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002760byte Map::bit_field2() {
2761 return READ_BYTE_FIELD(this, kBitField2Offset);
2762}
2763
2764
2765void Map::set_bit_field2(byte value) {
2766 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2767}
2768
2769
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002770void Map::set_non_instance_prototype(bool value) {
2771 if (value) {
2772 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2773 } else {
2774 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2775 }
2776}
2777
2778
2779bool Map::has_non_instance_prototype() {
2780 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2781}
2782
2783
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002784void Map::set_function_with_prototype(bool value) {
2785 if (value) {
2786 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2787 } else {
2788 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2789 }
2790}
2791
2792
2793bool Map::function_with_prototype() {
2794 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2795}
2796
2797
ager@chromium.org870a0b62008-11-04 11:43:05 +00002798void Map::set_is_access_check_needed(bool access_check_needed) {
2799 if (access_check_needed) {
2800 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2801 } else {
2802 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2803 }
2804}
2805
2806
2807bool Map::is_access_check_needed() {
2808 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2809}
2810
2811
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002812void Map::set_is_extensible(bool value) {
2813 if (value) {
2814 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2815 } else {
2816 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2817 }
2818}
2819
2820bool Map::is_extensible() {
2821 return ((1 << kIsExtensible) & bit_field2()) != 0;
2822}
2823
2824
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002825void Map::set_attached_to_shared_function_info(bool value) {
2826 if (value) {
2827 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2828 } else {
2829 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2830 }
2831}
2832
2833bool Map::attached_to_shared_function_info() {
2834 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2835}
2836
2837
2838void Map::set_is_shared(bool value) {
2839 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002840 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002841 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002842 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002843 }
2844}
2845
2846bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002847 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002848}
2849
2850
2851JSFunction* Map::unchecked_constructor() {
2852 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2853}
2854
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002855
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002856Code::Flags Code::flags() {
2857 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2858}
2859
2860
2861void Code::set_flags(Code::Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00002862 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= KindField::kMax + 1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002863 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002864 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2865 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002866 ExtractArgumentsCountFromFlags(flags) >= 0);
2867 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2868}
2869
2870
2871Code::Kind Code::kind() {
2872 return ExtractKindFromFlags(flags());
2873}
2874
2875
kasper.lund7276f142008-07-30 08:49:36 +00002876InlineCacheState Code::ic_state() {
2877 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002878 // Only allow uninitialized or debugger states for non-IC code
2879 // objects. This is used in the debugger to determine whether or not
2880 // a call to code object has been replaced with a debug break call.
2881 ASSERT(is_inline_cache_stub() ||
2882 result == UNINITIALIZED ||
2883 result == DEBUG_BREAK ||
2884 result == DEBUG_PREPARE_STEP_IN);
2885 return result;
2886}
2887
2888
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002889Code::ExtraICState Code::extra_ic_state() {
2890 ASSERT(is_inline_cache_stub());
2891 return ExtractExtraICStateFromFlags(flags());
2892}
2893
2894
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002895PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002896 return ExtractTypeFromFlags(flags());
2897}
2898
2899
2900int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002901 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002902 return ExtractArgumentsCountFromFlags(flags());
2903}
2904
2905
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002906int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002907 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002908 kind() == UNARY_OP_IC ||
2909 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002910 kind() == COMPARE_IC ||
2911 kind() == TO_BOOLEAN_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002912 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002913}
2914
2915
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002916void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002917 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002918 kind() == UNARY_OP_IC ||
2919 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002920 kind() == COMPARE_IC ||
2921 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002922 ASSERT(0 <= major && major < 256);
2923 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002924}
2925
2926
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00002927bool Code::is_pregenerated() {
2928 return kind() == STUB && IsPregeneratedField::decode(flags());
2929}
2930
2931
2932void Code::set_is_pregenerated(bool value) {
2933 ASSERT(kind() == STUB);
2934 Flags f = flags();
2935 f = static_cast<Flags>(IsPregeneratedField::update(f, value));
2936 set_flags(f);
2937}
2938
2939
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002940bool Code::optimizable() {
2941 ASSERT(kind() == FUNCTION);
2942 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2943}
2944
2945
2946void Code::set_optimizable(bool value) {
2947 ASSERT(kind() == FUNCTION);
2948 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2949}
2950
2951
2952bool Code::has_deoptimization_support() {
2953 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00002954 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2955 return FullCodeFlagsHasDeoptimizationSupportField::decode(flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002956}
2957
2958
2959void Code::set_has_deoptimization_support(bool value) {
2960 ASSERT(kind() == FUNCTION);
lrn@chromium.org34e60782011-09-15 07:25:40 +00002961 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2962 flags = FullCodeFlagsHasDeoptimizationSupportField::update(flags, value);
2963 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
2964}
2965
2966
2967bool Code::has_debug_break_slots() {
2968 ASSERT(kind() == FUNCTION);
2969 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2970 return FullCodeFlagsHasDebugBreakSlotsField::decode(flags);
2971}
2972
2973
2974void Code::set_has_debug_break_slots(bool value) {
2975 ASSERT(kind() == FUNCTION);
2976 byte flags = READ_BYTE_FIELD(this, kFullCodeFlags);
2977 flags = FullCodeFlagsHasDebugBreakSlotsField::update(flags, value);
2978 WRITE_BYTE_FIELD(this, kFullCodeFlags, flags);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002979}
2980
2981
2982int Code::allow_osr_at_loop_nesting_level() {
2983 ASSERT(kind() == FUNCTION);
2984 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
2985}
2986
2987
2988void Code::set_allow_osr_at_loop_nesting_level(int level) {
2989 ASSERT(kind() == FUNCTION);
2990 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
2991 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
2992}
2993
2994
2995unsigned Code::stack_slots() {
2996 ASSERT(kind() == OPTIMIZED_FUNCTION);
2997 return READ_UINT32_FIELD(this, kStackSlotsOffset);
2998}
2999
3000
3001void Code::set_stack_slots(unsigned slots) {
3002 ASSERT(kind() == OPTIMIZED_FUNCTION);
3003 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
3004}
3005
3006
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003007unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003008 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003009 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003010}
3011
3012
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003013void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003014 ASSERT(kind() == OPTIMIZED_FUNCTION);
3015 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003016 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003017}
3018
3019
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003020unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003021 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003022 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003023}
3024
3025
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003026void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003027 ASSERT(kind() == FUNCTION);
3028 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003029 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003030}
3031
3032
3033CheckType Code::check_type() {
3034 ASSERT(is_call_stub() || is_keyed_call_stub());
3035 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
3036 return static_cast<CheckType>(type);
3037}
3038
3039
3040void Code::set_check_type(CheckType value) {
3041 ASSERT(is_call_stub() || is_keyed_call_stub());
3042 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
3043}
3044
3045
danno@chromium.org40cb8782011-05-25 07:58:50 +00003046byte Code::unary_op_type() {
3047 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003048 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
3049}
3050
3051
danno@chromium.org40cb8782011-05-25 07:58:50 +00003052void Code::set_unary_op_type(byte value) {
3053 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00003054 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
3055}
3056
3057
danno@chromium.org40cb8782011-05-25 07:58:50 +00003058byte Code::binary_op_type() {
3059 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003060 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
3061}
3062
3063
danno@chromium.org40cb8782011-05-25 07:58:50 +00003064void Code::set_binary_op_type(byte value) {
3065 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003066 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
3067}
3068
3069
danno@chromium.org40cb8782011-05-25 07:58:50 +00003070byte Code::binary_op_result_type() {
3071 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003072 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
3073}
3074
3075
danno@chromium.org40cb8782011-05-25 07:58:50 +00003076void Code::set_binary_op_result_type(byte value) {
3077 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003078 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
3079}
3080
3081
3082byte Code::compare_state() {
3083 ASSERT(is_compare_ic_stub());
3084 return READ_BYTE_FIELD(this, kCompareStateOffset);
3085}
3086
3087
3088void Code::set_compare_state(byte value) {
3089 ASSERT(is_compare_ic_stub());
3090 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
3091}
3092
3093
ricow@chromium.org9fa09672011-07-25 11:05:35 +00003094byte Code::to_boolean_state() {
3095 ASSERT(is_to_boolean_ic_stub());
3096 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
3097}
3098
3099
3100void Code::set_to_boolean_state(byte value) {
3101 ASSERT(is_to_boolean_ic_stub());
3102 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
3103}
3104
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003105
3106bool Code::has_function_cache() {
3107 ASSERT(kind() == STUB);
3108 return READ_BYTE_FIELD(this, kHasFunctionCacheOffset) != 0;
3109}
3110
3111
3112void Code::set_has_function_cache(bool flag) {
3113 ASSERT(kind() == STUB);
3114 WRITE_BYTE_FIELD(this, kHasFunctionCacheOffset, flag);
3115}
3116
3117
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003118bool Code::is_inline_cache_stub() {
3119 Kind kind = this->kind();
3120 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
3121}
3122
3123
3124Code::Flags Code::ComputeFlags(Kind kind,
kasper.lund7276f142008-07-30 08:49:36 +00003125 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003126 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003127 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003128 int argc,
3129 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003130 // Extra IC state is only allowed for call IC stubs or for store IC
3131 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003132 ASSERT(extra_ic_state == kNoExtraICState ||
lrn@chromium.org34e60782011-09-15 07:25:40 +00003133 kind == CALL_IC ||
3134 kind == STORE_IC ||
3135 kind == KEYED_STORE_IC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003136 // Compute the bit mask.
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003137 int bits = KindField::encode(kind)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003138 | ICStateField::encode(ic_state)
3139 | TypeField::encode(type)
3140 | ExtraICStateField::encode(extra_ic_state)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003141 | (argc << kArgumentsCountShift)
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003142 | CacheHolderField::encode(holder);
3143 return static_cast<Flags>(bits);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003144}
3145
3146
3147Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
3148 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003149 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003150 InlineCacheHolderFlag holder,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003151 int argc) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003152 return ComputeFlags(kind, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003153}
3154
3155
3156Code::Kind Code::ExtractKindFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003157 return KindField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003158}
3159
3160
kasper.lund7276f142008-07-30 08:49:36 +00003161InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003162 return ICStateField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003163}
3164
3165
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003166Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003167 return ExtraICStateField::decode(flags);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00003168}
3169
3170
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003171PropertyType Code::ExtractTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003172 return TypeField::decode(flags);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003173}
3174
3175
3176int Code::ExtractArgumentsCountFromFlags(Flags flags) {
lrn@chromium.org34e60782011-09-15 07:25:40 +00003177 return (flags & kArgumentsCountMask) >> kArgumentsCountShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003178}
3179
3180
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003181InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003182 return CacheHolderField::decode(flags);
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003183}
3184
3185
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003186Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00003187 int bits = flags & ~TypeField::kMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003188 return static_cast<Flags>(bits);
3189}
3190
3191
ager@chromium.org8bb60582008-12-11 12:02:20 +00003192Code* Code::GetCodeFromTargetAddress(Address address) {
3193 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3194 // GetCodeFromTargetAddress might be called when marking objects during mark
3195 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3196 // Code::cast. Code::cast does not work when the object's map is
3197 // marked.
3198 Code* result = reinterpret_cast<Code*>(code);
3199 return result;
3200}
3201
3202
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003203Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3204 return HeapObject::
3205 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3206}
3207
3208
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003209Object* Map::prototype() {
3210 return READ_FIELD(this, kPrototypeOffset);
3211}
3212
3213
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003214void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003215 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003216 WRITE_FIELD(this, kPrototypeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003217 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, value, mode);
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003218}
3219
3220
danno@chromium.org40cb8782011-05-25 07:58:50 +00003221DescriptorArray* Map::instance_descriptors() {
3222 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3223 if (object->IsSmi()) {
3224 return HEAP->empty_descriptor_array();
3225 } else {
3226 return DescriptorArray::cast(object);
3227 }
3228}
3229
3230
3231void Map::init_instance_descriptors() {
3232 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3233}
3234
3235
3236void Map::clear_instance_descriptors() {
3237 Object* object = READ_FIELD(this,
3238 kInstanceDescriptorsOrBitField3Offset);
3239 if (!object->IsSmi()) {
3240 WRITE_FIELD(
3241 this,
3242 kInstanceDescriptorsOrBitField3Offset,
3243 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3244 }
3245}
3246
3247
3248void Map::set_instance_descriptors(DescriptorArray* value,
3249 WriteBarrierMode mode) {
3250 Object* object = READ_FIELD(this,
3251 kInstanceDescriptorsOrBitField3Offset);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003252 Heap* heap = GetHeap();
3253 if (value == heap->empty_descriptor_array()) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00003254 clear_instance_descriptors();
3255 return;
3256 } else {
3257 if (object->IsSmi()) {
3258 value->set_bit_field3_storage(Smi::cast(object)->value());
3259 } else {
3260 value->set_bit_field3_storage(
3261 DescriptorArray::cast(object)->bit_field3_storage());
3262 }
3263 }
3264 ASSERT(!is_shared());
3265 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003266 CONDITIONAL_WRITE_BARRIER(
3267 heap, this, kInstanceDescriptorsOrBitField3Offset, value, mode);
danno@chromium.org40cb8782011-05-25 07:58:50 +00003268}
3269
3270
3271int Map::bit_field3() {
3272 Object* object = READ_FIELD(this,
3273 kInstanceDescriptorsOrBitField3Offset);
3274 if (object->IsSmi()) {
3275 return Smi::cast(object)->value();
3276 } else {
3277 return DescriptorArray::cast(object)->bit_field3_storage();
3278 }
3279}
3280
3281
3282void Map::set_bit_field3(int value) {
3283 ASSERT(Smi::IsValid(value));
3284 Object* object = READ_FIELD(this,
3285 kInstanceDescriptorsOrBitField3Offset);
3286 if (object->IsSmi()) {
3287 WRITE_FIELD(this,
3288 kInstanceDescriptorsOrBitField3Offset,
3289 Smi::FromInt(value));
3290 } else {
3291 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3292 }
3293}
3294
3295
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003296FixedArray* Map::unchecked_prototype_transitions() {
3297 return reinterpret_cast<FixedArray*>(
3298 READ_FIELD(this, kPrototypeTransitionsOffset));
3299}
3300
3301
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003302ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003303ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003304ACCESSORS(Map, constructor, Object, kConstructorOffset)
3305
3306ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
3307ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003308ACCESSORS(JSFunction,
3309 next_function_link,
3310 Object,
3311 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003312
3313ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3314ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003315ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003316
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003317ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003318
3319ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3320ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3321ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3322ACCESSORS(AccessorInfo, name, Object, kNameOffset)
3323ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
3324
3325ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3326ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3327ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3328
3329ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3330ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3331ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3332ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3333ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3334ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3335
3336ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3337ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3338
3339ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3340ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3341
3342ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3343ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003344ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3345 kPropertyAccessorsOffset)
3346ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3347 kPrototypeTemplateOffset)
3348ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3349ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3350 kNamedPropertyHandlerOffset)
3351ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3352 kIndexedPropertyHandlerOffset)
3353ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3354 kInstanceTemplateOffset)
3355ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3356ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003357ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3358 kInstanceCallHandlerOffset)
3359ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3360 kAccessCheckInfoOffset)
3361ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
3362
3363ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003364ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3365 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003366
3367ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3368ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3369
3370ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3371
3372ACCESSORS(Script, source, Object, kSourceOffset)
3373ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003374ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003375ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3376ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003377ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003378ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003379ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003380ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003381ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003382ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003383ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003384ACCESSORS(Script, eval_from_instructions_offset, Smi,
3385 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003386
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003387#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003388ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3389ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3390ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3391ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3392
3393ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3394ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3395ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3396ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003397#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003398
3399ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003400ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3401ACCESSORS(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003402ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3403 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003404ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003405ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3406ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003407ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003408ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3409 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003410
3411BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3412 kHiddenPrototypeBit)
3413BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3414BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3415 kNeedsAccessCheckBit)
ricow@chromium.org2c99e282011-07-28 09:15:17 +00003416BOOL_ACCESSORS(FunctionTemplateInfo, flag, read_only_prototype,
3417 kReadOnlyPrototypeBit)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003418BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3419 kIsExpressionBit)
3420BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3421 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003422BOOL_GETTER(SharedFunctionInfo,
3423 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003424 has_only_simple_this_property_assignments,
3425 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003426BOOL_ACCESSORS(SharedFunctionInfo,
3427 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003428 allows_lazy_compilation,
3429 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003430BOOL_ACCESSORS(SharedFunctionInfo,
3431 compiler_hints,
3432 uses_arguments,
3433 kUsesArguments)
3434BOOL_ACCESSORS(SharedFunctionInfo,
3435 compiler_hints,
3436 has_duplicate_parameters,
3437 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003438
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003439
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003440#if V8_HOST_ARCH_32_BIT
3441SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3442SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003443 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003444SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003445 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003446SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3447SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003448 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003449SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3450SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003451 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003452SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003453 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003454SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003455 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003456SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003457#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003458
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003459#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003460 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003461 int holder::name() { \
3462 int value = READ_INT_FIELD(this, offset); \
3463 ASSERT(kHeapObjectTag == 1); \
3464 ASSERT((value & kHeapObjectTag) == 0); \
3465 return value >> 1; \
3466 } \
3467 void holder::set_##name(int value) { \
3468 ASSERT(kHeapObjectTag == 1); \
3469 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3470 (value & 0xC0000000) == 0x000000000); \
3471 WRITE_INT_FIELD(this, \
3472 offset, \
3473 (value << 1) & ~kHeapObjectTag); \
3474 }
3475
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003476#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3477 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003478 INT_ACCESSORS(holder, name, offset)
3479
3480
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003481PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003482PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3483 formal_parameter_count,
3484 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003485
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003486PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3487 expected_nof_properties,
3488 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003489PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3490
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003491PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3492PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3493 start_position_and_type,
3494 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003495
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003496PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3497 function_token_position,
3498 kFunctionTokenPositionOffset)
3499PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3500 compiler_hints,
3501 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003502
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003503PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3504 this_property_assignments_count,
3505 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003506PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003507#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003508
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003509
3510int SharedFunctionInfo::construction_count() {
3511 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3512}
3513
3514
3515void SharedFunctionInfo::set_construction_count(int value) {
3516 ASSERT(0 <= value && value < 256);
3517 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3518}
3519
3520
whesse@chromium.org7b260152011-06-20 15:33:18 +00003521BOOL_ACCESSORS(SharedFunctionInfo,
3522 compiler_hints,
3523 live_objects_may_exist,
3524 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003525
3526
3527bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003528 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003529}
3530
3531
whesse@chromium.org7b260152011-06-20 15:33:18 +00003532BOOL_GETTER(SharedFunctionInfo,
3533 compiler_hints,
3534 optimization_disabled,
3535 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003536
3537
3538void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3539 set_compiler_hints(BooleanBit::set(compiler_hints(),
3540 kOptimizationDisabled,
3541 disable));
3542 // If disabling optimizations we reflect that in the code object so
3543 // it will not be counted as optimizable code.
3544 if ((code()->kind() == Code::FUNCTION) && disable) {
3545 code()->set_optimizable(false);
3546 }
3547}
3548
3549
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003550BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, strict_mode,
whesse@chromium.org7b260152011-06-20 15:33:18 +00003551 kStrictModeFunction)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003552BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, native, kNative)
3553BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints,
3554 name_should_print_as_anonymous,
3555 kNameShouldPrintAsAnonymous)
3556BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, bound, kBoundFunction)
3557BOOL_ACCESSORS(SharedFunctionInfo, compiler_hints, is_anonymous, kIsAnonymous)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003558
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003559ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3560ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3561
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003562ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3563
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003564bool Script::HasValidSource() {
3565 Object* src = this->source();
3566 if (!src->IsString()) return true;
3567 String* src_str = String::cast(src);
3568 if (!StringShape(src_str).IsExternal()) return true;
3569 if (src_str->IsAsciiRepresentation()) {
3570 return ExternalAsciiString::cast(src)->resource() != NULL;
3571 } else if (src_str->IsTwoByteRepresentation()) {
3572 return ExternalTwoByteString::cast(src)->resource() != NULL;
3573 }
3574 return true;
3575}
3576
3577
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003578void SharedFunctionInfo::DontAdaptArguments() {
3579 ASSERT(code()->kind() == Code::BUILTIN);
3580 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3581}
3582
3583
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003584int SharedFunctionInfo::start_position() {
3585 return start_position_and_type() >> kStartPositionShift;
3586}
3587
3588
3589void SharedFunctionInfo::set_start_position(int start_position) {
3590 set_start_position_and_type((start_position << kStartPositionShift)
3591 | (start_position_and_type() & ~kStartPositionMask));
3592}
3593
3594
3595Code* SharedFunctionInfo::code() {
3596 return Code::cast(READ_FIELD(this, kCodeOffset));
3597}
3598
3599
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003600Code* SharedFunctionInfo::unchecked_code() {
3601 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3602}
3603
3604
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003605void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003606 WRITE_FIELD(this, kCodeOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003607 CONDITIONAL_WRITE_BARRIER(value->GetHeap(), this, kCodeOffset, value, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003608}
3609
3610
ager@chromium.orgb5737492010-07-15 09:29:43 +00003611SerializedScopeInfo* SharedFunctionInfo::scope_info() {
3612 return reinterpret_cast<SerializedScopeInfo*>(
3613 READ_FIELD(this, kScopeInfoOffset));
3614}
3615
3616
3617void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
3618 WriteBarrierMode mode) {
3619 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003620 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3621 this,
3622 kScopeInfoOffset,
3623 reinterpret_cast<Object*>(value),
3624 mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003625}
3626
3627
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003628Smi* SharedFunctionInfo::deopt_counter() {
3629 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3630}
3631
3632
3633void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3634 WRITE_FIELD(this, kDeoptCounterOffset, value);
3635}
3636
3637
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003638bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003639 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003640 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003641}
3642
3643
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003644bool SharedFunctionInfo::IsApiFunction() {
3645 return function_data()->IsFunctionTemplateInfo();
3646}
3647
3648
3649FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3650 ASSERT(IsApiFunction());
3651 return FunctionTemplateInfo::cast(function_data());
3652}
3653
3654
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003655bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003656 return function_data()->IsSmi();
3657}
3658
3659
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003660BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3661 ASSERT(HasBuiltinFunctionId());
3662 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003663}
3664
3665
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003666int SharedFunctionInfo::code_age() {
3667 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3668}
3669
3670
3671void SharedFunctionInfo::set_code_age(int code_age) {
3672 set_compiler_hints(compiler_hints() |
3673 ((code_age & kCodeAgeMask) << kCodeAgeShift));
3674}
3675
3676
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003677bool SharedFunctionInfo::has_deoptimization_support() {
3678 Code* code = this->code();
3679 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3680}
3681
3682
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003683bool JSFunction::IsBuiltin() {
3684 return context()->global()->IsJSBuiltinsObject();
3685}
3686
3687
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003688bool JSFunction::NeedsArgumentsAdaption() {
3689 return shared()->formal_parameter_count() !=
3690 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3691}
3692
3693
3694bool JSFunction::IsOptimized() {
3695 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3696}
3697
3698
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003699bool JSFunction::IsOptimizable() {
3700 return code()->kind() == Code::FUNCTION && code()->optimizable();
3701}
3702
3703
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003704bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003705 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003706}
3707
3708
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003709Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003710 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003711}
3712
3713
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003714Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003715 return reinterpret_cast<Code*>(
3716 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003717}
3718
3719
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003720void JSFunction::set_code(Code* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003721 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003722 Address entry = value->entry();
3723 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003724 GetHeap()->incremental_marking()->RecordWriteOfCodeEntry(
3725 this,
3726 HeapObject::RawField(this, kCodeEntryOffset),
3727 value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003728}
3729
3730
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003731void JSFunction::ReplaceCode(Code* code) {
3732 bool was_optimized = IsOptimized();
3733 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3734
3735 set_code(code);
3736
3737 // Add/remove the function from the list of optimized functions for this
3738 // context based on the state change.
3739 if (!was_optimized && is_optimized) {
3740 context()->global_context()->AddOptimizedFunction(this);
3741 }
3742 if (was_optimized && !is_optimized) {
3743 context()->global_context()->RemoveOptimizedFunction(this);
3744 }
3745}
3746
3747
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003748Context* JSFunction::context() {
3749 return Context::cast(READ_FIELD(this, kContextOffset));
3750}
3751
3752
3753Object* JSFunction::unchecked_context() {
3754 return READ_FIELD(this, kContextOffset);
3755}
3756
3757
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003758SharedFunctionInfo* JSFunction::unchecked_shared() {
3759 return reinterpret_cast<SharedFunctionInfo*>(
3760 READ_FIELD(this, kSharedFunctionInfoOffset));
3761}
3762
3763
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003764void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003765 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003766 WRITE_FIELD(this, kContextOffset, value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003767 WRITE_BARRIER(GetHeap(), this, kContextOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003768}
3769
3770ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3771 kPrototypeOrInitialMapOffset)
3772
3773
3774Map* JSFunction::initial_map() {
3775 return Map::cast(prototype_or_initial_map());
3776}
3777
3778
3779void JSFunction::set_initial_map(Map* value) {
3780 set_prototype_or_initial_map(value);
3781}
3782
3783
3784bool JSFunction::has_initial_map() {
3785 return prototype_or_initial_map()->IsMap();
3786}
3787
3788
3789bool JSFunction::has_instance_prototype() {
3790 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3791}
3792
3793
3794bool JSFunction::has_prototype() {
3795 return map()->has_non_instance_prototype() || has_instance_prototype();
3796}
3797
3798
3799Object* JSFunction::instance_prototype() {
3800 ASSERT(has_instance_prototype());
3801 if (has_initial_map()) return initial_map()->prototype();
3802 // When there is no initial map and the prototype is a JSObject, the
3803 // initial map field is used for the prototype field.
3804 return prototype_or_initial_map();
3805}
3806
3807
3808Object* JSFunction::prototype() {
3809 ASSERT(has_prototype());
3810 // If the function's prototype property has been set to a non-JSObject
3811 // value, that value is stored in the constructor field of the map.
3812 if (map()->has_non_instance_prototype()) return map()->constructor();
3813 return instance_prototype();
3814}
3815
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003816bool JSFunction::should_have_prototype() {
3817 return map()->function_with_prototype();
3818}
3819
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003820
3821bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003822 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003823}
3824
3825
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003826int JSFunction::NumberOfLiterals() {
3827 return literals()->length();
3828}
3829
3830
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003831Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003832 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003833 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003834}
3835
3836
3837void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3838 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003839 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003840 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003841 WRITE_BARRIER(GetHeap(), this, OffsetOfFunctionWithId(id), value);
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003842}
3843
3844
3845Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003846 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003847 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3848}
3849
3850
3851void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3852 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003853 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003854 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003855 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003856}
3857
3858
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003859ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003860ACCESSORS(JSProxy, hash, Object, kHashOffset)
lrn@chromium.org34e60782011-09-15 07:25:40 +00003861ACCESSORS(JSFunctionProxy, call_trap, Object, kCallTrapOffset)
3862ACCESSORS(JSFunctionProxy, construct_trap, Object, kConstructTrapOffset)
3863
3864
3865void JSProxy::InitializeBody(int object_size, Object* value) {
3866 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
3867 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
3868 WRITE_FIELD(this, offset, value);
3869 }
3870}
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003871
3872
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003873ACCESSORS(JSWeakMap, table, Object, kTableOffset)
3874ACCESSORS(JSWeakMap, next, Object, kNextOffset)
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00003875
3876
3877ObjectHashTable* JSWeakMap::unchecked_table() {
3878 return reinterpret_cast<ObjectHashTable*>(READ_FIELD(this, kTableOffset));
3879}
3880
3881
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003882Address Foreign::address() {
3883 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003884}
3885
3886
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003887void Foreign::set_address(Address value) {
3888 WRITE_INTPTR_FIELD(this, kAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003889}
3890
3891
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003892ACCESSORS(JSValue, value, Object, kValueOffset)
3893
3894
3895JSValue* JSValue::cast(Object* obj) {
3896 ASSERT(obj->IsJSValue());
3897 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3898 return reinterpret_cast<JSValue*>(obj);
3899}
3900
3901
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003902ACCESSORS(JSMessageObject, type, String, kTypeOffset)
3903ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
3904ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
3905ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
3906ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
3907SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
3908SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
3909
3910
3911JSMessageObject* JSMessageObject::cast(Object* obj) {
3912 ASSERT(obj->IsJSMessageObject());
3913 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
3914 return reinterpret_cast<JSMessageObject*>(obj);
3915}
3916
3917
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003918INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003919ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003920ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003921ACCESSORS(Code, next_code_flushing_candidate,
3922 Object, kNextCodeFlushingCandidateOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003923
3924
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003925byte* Code::instruction_start() {
3926 return FIELD_ADDR(this, kHeaderSize);
3927}
3928
3929
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003930byte* Code::instruction_end() {
3931 return instruction_start() + instruction_size();
3932}
3933
3934
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003935int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003936 return RoundUp(instruction_size(), kObjectAlignment);
3937}
3938
3939
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003940FixedArray* Code::unchecked_deoptimization_data() {
3941 return reinterpret_cast<FixedArray*>(
3942 READ_FIELD(this, kDeoptimizationDataOffset));
3943}
3944
3945
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003946ByteArray* Code::unchecked_relocation_info() {
3947 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003948}
3949
3950
3951byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003952 return unchecked_relocation_info()->GetDataStartAddress();
3953}
3954
3955
3956int Code::relocation_size() {
3957 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003958}
3959
3960
3961byte* Code::entry() {
3962 return instruction_start();
3963}
3964
3965
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00003966bool Code::contains(byte* inner_pointer) {
3967 return (address() <= inner_pointer) && (inner_pointer <= address() + Size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003968}
3969
3970
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003971ACCESSORS(JSArray, length, Object, kLengthOffset)
3972
3973
ager@chromium.org236ad962008-09-25 09:45:57 +00003974ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00003975
3976
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003977JSRegExp::Type JSRegExp::TypeTag() {
3978 Object* data = this->data();
3979 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
3980 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
3981 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00003982}
3983
3984
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003985JSRegExp::Type JSRegExp::TypeTagUnchecked() {
3986 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
3987 return static_cast<JSRegExp::Type>(smi->value());
3988}
3989
3990
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00003991int JSRegExp::CaptureCount() {
3992 switch (TypeTag()) {
3993 case ATOM:
3994 return 0;
3995 case IRREGEXP:
3996 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
3997 default:
3998 UNREACHABLE();
3999 return -1;
4000 }
4001}
4002
4003
ager@chromium.orga74f0da2008-12-03 16:05:52 +00004004JSRegExp::Flags JSRegExp::GetFlags() {
4005 ASSERT(this->data()->IsFixedArray());
4006 Object* data = this->data();
4007 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
4008 return Flags(smi->value());
4009}
4010
4011
4012String* JSRegExp::Pattern() {
4013 ASSERT(this->data()->IsFixedArray());
4014 Object* data = this->data();
4015 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
4016 return pattern;
4017}
4018
4019
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00004020Object* JSRegExp::DataAt(int index) {
4021 ASSERT(TypeTag() != NOT_COMPILED);
4022 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00004023}
4024
4025
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004026Object* JSRegExp::DataAtUnchecked(int index) {
4027 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4028 int offset = FixedArray::kHeaderSize + index * kPointerSize;
4029 return READ_FIELD(fa, offset);
4030}
4031
4032
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00004033void JSRegExp::SetDataAt(int index, Object* value) {
4034 ASSERT(TypeTag() != NOT_COMPILED);
4035 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4036 FixedArray::cast(data())->set(index, value);
4037}
4038
4039
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004040void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
4041 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
4042 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
4043 if (value->IsSmi()) {
4044 fa->set_unchecked(index, Smi::cast(value));
4045 } else {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004046 // We only do this during GC, so we don't need to notify the write barrier.
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00004047 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
4048 }
4049}
4050
4051
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004052ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004053 ElementsKind kind = map()->elements_kind();
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004054#if DEBUG
4055 FixedArrayBase* fixed_array =
4056 reinterpret_cast<FixedArrayBase*>(READ_FIELD(this, kElementsOffset));
4057 Map* map = fixed_array->map();
4058 ASSERT(((kind == FAST_ELEMENTS || kind == FAST_SMI_ONLY_ELEMENTS) &&
4059 (map == GetHeap()->fixed_array_map() ||
4060 map == GetHeap()->fixed_cow_array_map())) ||
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004061 (kind == FAST_DOUBLE_ELEMENTS &&
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004062 fixed_array->IsFixedDoubleArray()) ||
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004063 (kind == DICTIONARY_ELEMENTS &&
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004064 fixed_array->IsFixedArray() &&
4065 fixed_array->IsDictionary()) ||
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004066 (kind > DICTIONARY_ELEMENTS));
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004067#endif
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00004068 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004069}
4070
4071
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004072ElementsAccessor* JSObject::GetElementsAccessor() {
4073 return ElementsAccessor::ForKind(GetElementsKind());
4074}
4075
4076
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004077bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004078 return GetElementsKind() == FAST_ELEMENTS;
4079}
4080
4081
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004082bool JSObject::HasFastSmiOnlyElements() {
4083 return GetElementsKind() == FAST_SMI_ONLY_ELEMENTS;
4084}
4085
4086
4087bool JSObject::HasFastTypeElements() {
4088 ElementsKind elements_kind = GetElementsKind();
4089 return elements_kind == FAST_SMI_ONLY_ELEMENTS ||
4090 elements_kind == FAST_ELEMENTS;
4091}
4092
4093
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00004094bool JSObject::HasFastDoubleElements() {
4095 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
4096}
4097
4098
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004099bool JSObject::HasDictionaryElements() {
4100 return GetElementsKind() == DICTIONARY_ELEMENTS;
4101}
4102
4103
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004104bool JSObject::HasNonStrictArgumentsElements() {
4105 return GetElementsKind() == NON_STRICT_ARGUMENTS_ELEMENTS;
4106}
4107
4108
ager@chromium.org3811b432009-10-28 14:53:37 +00004109bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004110 HeapObject* array = elements();
4111 ASSERT(array != NULL);
4112 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00004113}
4114
4115
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004116#define EXTERNAL_ELEMENTS_CHECK(name, type) \
4117bool JSObject::HasExternal##name##Elements() { \
4118 HeapObject* array = elements(); \
4119 ASSERT(array != NULL); \
4120 if (!array->IsHeapObject()) \
4121 return false; \
4122 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004123}
4124
4125
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004126EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4127EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4128EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4129EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4130 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4131EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4132EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4133 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4134EXTERNAL_ELEMENTS_CHECK(Float,
4135 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004136EXTERNAL_ELEMENTS_CHECK(Double,
4137 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004138EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004139
4140
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004141bool JSObject::HasNamedInterceptor() {
4142 return map()->has_named_interceptor();
4143}
4144
4145
4146bool JSObject::HasIndexedInterceptor() {
4147 return map()->has_indexed_interceptor();
4148}
4149
4150
ager@chromium.org5c838252010-02-19 08:53:10 +00004151bool JSObject::AllowsSetElementsLength() {
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004152 bool result = elements()->IsFixedArray() ||
4153 elements()->IsFixedDoubleArray();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004154 ASSERT(result == !HasExternalArrayElements());
ager@chromium.org5c838252010-02-19 08:53:10 +00004155 return result;
4156}
4157
4158
lrn@chromium.org303ada72010-10-27 09:33:13 +00004159MaybeObject* JSObject::EnsureWritableFastElements() {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004160 ASSERT(HasFastTypeElements());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004161 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004162 Isolate* isolate = GetIsolate();
4163 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004164 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004165 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4166 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004167 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4168 return maybe_writable_elems;
4169 }
4170 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004171 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004172 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004173 return writable_elems;
4174}
4175
4176
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004177StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004178 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004179 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004180}
4181
4182
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004183NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004184 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004185 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004186}
4187
4188
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004189bool String::IsHashFieldComputed(uint32_t field) {
4190 return (field & kHashNotComputedMask) == 0;
4191}
4192
4193
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004194bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004195 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004196}
4197
4198
4199uint32_t String::Hash() {
4200 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004201 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004202 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004203 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004204 return ComputeAndSetHash();
4205}
4206
4207
ager@chromium.org7c537e22008-10-16 08:43:32 +00004208StringHasher::StringHasher(int length)
4209 : length_(length),
4210 raw_running_hash_(0),
4211 array_index_(0),
4212 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4213 is_first_char_(true),
4214 is_valid_(true) { }
4215
4216
4217bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004218 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004219}
4220
4221
4222void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004223 // Use the Jenkins one-at-a-time hash function to update the hash
4224 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004225 raw_running_hash_ += c;
4226 raw_running_hash_ += (raw_running_hash_ << 10);
4227 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004228 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004229 if (is_array_index_) {
4230 if (c < '0' || c > '9') {
4231 is_array_index_ = false;
4232 } else {
4233 int d = c - '0';
4234 if (is_first_char_) {
4235 is_first_char_ = false;
4236 if (c == '0' && length_ > 1) {
4237 is_array_index_ = false;
4238 return;
4239 }
4240 }
4241 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4242 is_array_index_ = false;
4243 } else {
4244 array_index_ = array_index_ * 10 + d;
4245 }
4246 }
4247 }
4248}
4249
4250
4251void StringHasher::AddCharacterNoIndex(uc32 c) {
4252 ASSERT(!is_array_index());
4253 raw_running_hash_ += c;
4254 raw_running_hash_ += (raw_running_hash_ << 10);
4255 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4256}
4257
4258
4259uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004260 // Get the calculated raw hash value and do some more bit ops to distribute
4261 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004262 uint32_t result = raw_running_hash_;
4263 result += (result << 3);
4264 result ^= (result >> 11);
4265 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004266 if (result == 0) {
4267 result = 27;
4268 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004269 return result;
4270}
4271
4272
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004273template <typename schar>
4274uint32_t HashSequentialString(const schar* chars, int length) {
4275 StringHasher hasher(length);
4276 if (!hasher.has_trivial_hash()) {
4277 int i;
4278 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4279 hasher.AddCharacter(chars[i]);
4280 }
4281 for (; i < length; i++) {
4282 hasher.AddCharacterNoIndex(chars[i]);
4283 }
4284 }
4285 return hasher.GetHashField();
4286}
4287
4288
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004289bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004290 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004291 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4292 return false;
4293 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004294 return SlowAsArrayIndex(index);
4295}
4296
4297
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004298Object* JSReceiver::GetPrototype() {
4299 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004300}
4301
4302
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004303bool JSReceiver::HasProperty(String* name) {
4304 if (IsJSProxy()) {
4305 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4306 }
4307 return GetPropertyAttribute(name) != ABSENT;
4308}
4309
4310
4311bool JSReceiver::HasLocalProperty(String* name) {
4312 if (IsJSProxy()) {
4313 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4314 }
4315 return GetLocalPropertyAttribute(name) != ABSENT;
4316}
4317
4318
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004319PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004320 return GetPropertyAttributeWithReceiver(this, key);
4321}
4322
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004323// TODO(504): this may be useful in other places too where JSGlobalProxy
4324// is used.
4325Object* JSObject::BypassGlobalProxy() {
4326 if (IsJSGlobalProxy()) {
4327 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004328 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004329 ASSERT(proto->IsJSGlobalObject());
4330 return proto;
4331 }
4332 return this;
4333}
4334
4335
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004336MaybeObject* JSReceiver::GetIdentityHash(CreationFlag flag) {
4337 return IsJSProxy()
4338 ? JSProxy::cast(this)->GetIdentityHash(flag)
4339 : JSObject::cast(this)->GetIdentityHash(flag);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004340}
4341
4342
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004343bool JSReceiver::HasElement(uint32_t index) {
4344 if (IsJSProxy()) {
4345 return JSProxy::cast(this)->HasElementWithHandler(index);
4346 }
4347 return JSObject::cast(this)->HasElementWithReceiver(this, index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004348}
4349
4350
4351bool AccessorInfo::all_can_read() {
4352 return BooleanBit::get(flag(), kAllCanReadBit);
4353}
4354
4355
4356void AccessorInfo::set_all_can_read(bool value) {
4357 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4358}
4359
4360
4361bool AccessorInfo::all_can_write() {
4362 return BooleanBit::get(flag(), kAllCanWriteBit);
4363}
4364
4365
4366void AccessorInfo::set_all_can_write(bool value) {
4367 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4368}
4369
4370
ager@chromium.org870a0b62008-11-04 11:43:05 +00004371bool AccessorInfo::prohibits_overwriting() {
4372 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4373}
4374
4375
4376void AccessorInfo::set_prohibits_overwriting(bool value) {
4377 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4378}
4379
4380
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004381PropertyAttributes AccessorInfo::property_attributes() {
4382 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4383}
4384
4385
4386void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
kmillikin@chromium.org83e16822011-09-13 08:21:47 +00004387 set_flag(Smi::FromInt(AttributesField::update(flag()->value(), attributes)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004388}
4389
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004390
4391template<typename Shape, typename Key>
4392void Dictionary<Shape, Key>::SetEntry(int entry,
4393 Object* key,
4394 Object* value) {
4395 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4396}
4397
4398
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004399template<typename Shape, typename Key>
4400void Dictionary<Shape, Key>::SetEntry(int entry,
4401 Object* key,
4402 Object* value,
4403 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004404 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004405 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004406 AssertNoAllocation no_gc;
4407 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004408 FixedArray::set(index, key, mode);
4409 FixedArray::set(index+1, value, mode);
4410 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004411}
4412
4413
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004414bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4415 ASSERT(other->IsNumber());
4416 return key == static_cast<uint32_t>(other->Number());
4417}
4418
4419
4420uint32_t NumberDictionaryShape::Hash(uint32_t key) {
4421 return ComputeIntegerHash(key);
4422}
4423
4424
4425uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
4426 ASSERT(other->IsNumber());
4427 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
4428}
4429
4430
4431MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4432 return Isolate::Current()->heap()->NumberFromUint32(key);
4433}
4434
4435
4436bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4437 // We know that all entries in a hash table had their hash keys created.
4438 // Use that knowledge to have fast failure.
4439 if (key->Hash() != String::cast(other)->Hash()) return false;
4440 return key->Equals(String::cast(other));
4441}
4442
4443
4444uint32_t StringDictionaryShape::Hash(String* key) {
4445 return key->Hash();
4446}
4447
4448
4449uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4450 return String::cast(other)->Hash();
4451}
4452
4453
4454MaybeObject* StringDictionaryShape::AsObject(String* key) {
4455 return key;
4456}
4457
4458
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004459bool ObjectHashTableShape::IsMatch(JSReceiver* key, Object* other) {
4460 return key == JSReceiver::cast(other);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004461}
4462
4463
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004464uint32_t ObjectHashTableShape::Hash(JSReceiver* key) {
4465 MaybeObject* maybe_hash = key->GetIdentityHash(OMIT_CREATION);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004466 ASSERT(!maybe_hash->IsFailure());
4467 return Smi::cast(maybe_hash->ToObjectUnchecked())->value();
4468}
4469
4470
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004471uint32_t ObjectHashTableShape::HashForObject(JSReceiver* key, Object* other) {
4472 MaybeObject* maybe_hash =
4473 JSReceiver::cast(other)->GetIdentityHash(OMIT_CREATION);
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004474 ASSERT(!maybe_hash->IsFailure());
4475 return Smi::cast(maybe_hash->ToObjectUnchecked())->value();
4476}
4477
4478
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004479MaybeObject* ObjectHashTableShape::AsObject(JSReceiver* key) {
vegorov@chromium.org7943d462011-08-01 11:41:52 +00004480 return key;
4481}
4482
4483
kmillikin@chromium.org7c2628c2011-08-10 11:27:35 +00004484void ObjectHashTable::RemoveEntry(int entry) {
4485 RemoveEntry(entry, GetHeap());
4486}
4487
4488
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004489void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004490 // No write barrier is needed since empty_fixed_array is not in new space.
4491 // Please note this function is used during marking:
4492 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004493 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4494 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004495}
4496
4497
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004498void JSArray::EnsureSize(int required_size) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004499 ASSERT(HasFastTypeElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004500 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004501 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4502 if (elts->length() < required_size) {
4503 // Doubling in size would be overkill, but leave some slack to avoid
4504 // constantly growing.
4505 Expand(required_size + (required_size >> 3));
4506 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004507 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004508 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4509 // Expand will allocate a new backing store in new space even if the size
4510 // we asked for isn't larger than what we had before.
4511 Expand(required_size);
4512 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004513}
4514
4515
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004516void JSArray::set_length(Smi* length) {
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004517 // Don't need a write barrier for a Smi.
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004518 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4519}
4520
4521
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004522MaybeObject* JSArray::SetContent(FixedArray* storage) {
4523 MaybeObject* maybe_object = EnsureCanContainElements(storage);
4524 if (maybe_object->IsFailure()) return maybe_object;
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004525 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004526 set_elements(storage);
erik.corry@gmail.comc3b670f2011-10-05 21:44:48 +00004527 return this;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004528}
4529
4530
lrn@chromium.org303ada72010-10-27 09:33:13 +00004531MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004532 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004533 return GetHeap()->CopyFixedArray(this);
4534}
4535
4536
4537Relocatable::Relocatable(Isolate* isolate) {
4538 ASSERT(isolate == Isolate::Current());
4539 isolate_ = isolate;
4540 prev_ = isolate->relocatable_top();
4541 isolate->set_relocatable_top(this);
4542}
4543
4544
4545Relocatable::~Relocatable() {
4546 ASSERT(isolate_ == Isolate::Current());
4547 ASSERT_EQ(isolate_->relocatable_top(), this);
4548 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004549}
4550
4551
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004552int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4553 return map->instance_size();
4554}
4555
4556
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004557void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004558 v->VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004559 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004560}
4561
4562
4563template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004564void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004565 StaticVisitor::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
4570void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4571 typedef v8::String::ExternalAsciiStringResource Resource;
4572 v->VisitExternalAsciiString(
4573 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4574}
4575
4576
4577template<typename StaticVisitor>
4578void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4579 typedef v8::String::ExternalAsciiStringResource Resource;
4580 StaticVisitor::VisitExternalAsciiString(
4581 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4582}
4583
4584
4585void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4586 typedef v8::String::ExternalStringResource Resource;
4587 v->VisitExternalTwoByteString(
4588 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4589}
4590
4591
4592template<typename StaticVisitor>
4593void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4594 typedef v8::String::ExternalStringResource Resource;
4595 StaticVisitor::VisitExternalTwoByteString(
4596 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4597}
4598
4599#define SLOT_ADDR(obj, offset) \
4600 reinterpret_cast<Object**>((obj)->address() + offset)
4601
4602template<int start_offset, int end_offset, int size>
4603void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4604 HeapObject* obj,
4605 ObjectVisitor* v) {
4606 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4607}
4608
4609
4610template<int start_offset>
4611void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4612 int object_size,
4613 ObjectVisitor* v) {
4614 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4615}
4616
4617#undef SLOT_ADDR
4618
4619
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004620#undef CAST_ACCESSOR
4621#undef INT_ACCESSORS
4622#undef SMI_ACCESSORS
4623#undef ACCESSORS
4624#undef FIELD_ADDR
4625#undef READ_FIELD
4626#undef WRITE_FIELD
4627#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004628#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004629#undef READ_MEMADDR_FIELD
4630#undef WRITE_MEMADDR_FIELD
4631#undef READ_DOUBLE_FIELD
4632#undef WRITE_DOUBLE_FIELD
4633#undef READ_INT_FIELD
4634#undef WRITE_INT_FIELD
4635#undef READ_SHORT_FIELD
4636#undef WRITE_SHORT_FIELD
4637#undef READ_BYTE_FIELD
4638#undef WRITE_BYTE_FIELD
4639
4640
4641} } // namespace v8::internal
4642
4643#endif // V8_OBJECTS_INL_H_