blob: af03b5a849a9ec14b7bdfd802dd05aefc5ac806e [file] [log] [blame]
ager@chromium.org9258b6b2008-09-11 09:11:10 +00001// Copyright 2006-2008 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
38#include "objects.h"
39#include "contexts.h"
40#include "conversions-inl.h"
41#include "property.h"
42
kasperl@chromium.org71affb52009-05-26 05:44:31 +000043namespace v8 {
44namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000045
46PropertyDetails::PropertyDetails(Smi* smi) {
47 value_ = smi->value();
48}
49
50
51Smi* PropertyDetails::AsSmi() {
52 return Smi::FromInt(value_);
53}
54
55
56#define CAST_ACCESSOR(type) \
57 type* type::cast(Object* object) { \
58 ASSERT(object->Is##type()); \
59 return reinterpret_cast<type*>(object); \
60 }
61
62
63#define INT_ACCESSORS(holder, name, offset) \
64 int holder::name() { return READ_INT_FIELD(this, offset); } \
65 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
66
67
68#define ACCESSORS(holder, name, type, offset) \
69 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000070 void holder::set_##name(type* value, WriteBarrierMode mode) { \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000071 WRITE_FIELD(this, offset, value); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000072 CONDITIONAL_WRITE_BARRIER(this, offset, mode); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000073 }
74
75
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000076
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000077#define SMI_ACCESSORS(holder, name, offset) \
78 int holder::name() { \
79 Object* value = READ_FIELD(this, offset); \
80 return Smi::cast(value)->value(); \
81 } \
82 void holder::set_##name(int value) { \
83 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
84 }
85
86
87#define BOOL_ACCESSORS(holder, field, name, offset) \
88 bool holder::name() { \
89 return BooleanBit::get(field(), offset); \
90 } \
91 void holder::set_##name(bool value) { \
92 set_##field(BooleanBit::set(field(), offset, value)); \
93 }
94
95
96bool Object::IsSmi() {
97 return HAS_SMI_TAG(this);
98}
99
100
101bool Object::IsHeapObject() {
102 return HAS_HEAP_OBJECT_TAG(this);
103}
104
105
106bool Object::IsHeapNumber() {
107 return Object::IsHeapObject()
108 && HeapObject::cast(this)->map()->instance_type() == HEAP_NUMBER_TYPE;
109}
110
111
112bool Object::IsString() {
113 return Object::IsHeapObject()
114 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
115}
116
117
ager@chromium.org870a0b62008-11-04 11:43:05 +0000118bool Object::IsSymbol() {
119 if (!this->IsHeapObject()) return false;
120 uint32_t type = HeapObject::cast(this)->map()->instance_type();
121 return (type & (kIsNotStringMask | kIsSymbolMask)) ==
122 (kStringTag | kSymbolTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000123}
124
125
126bool Object::IsConsString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000127 if (!this->IsHeapObject()) return false;
128 uint32_t type = HeapObject::cast(this)->map()->instance_type();
129 return (type & (kIsNotStringMask | kStringRepresentationMask)) ==
130 (kStringTag | kConsStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000131}
132
133
ager@chromium.org870a0b62008-11-04 11:43:05 +0000134#ifdef DEBUG
135// These are for cast checks. If you need one of these in release
136// mode you should consider using a StringShape before moving it out
137// of the ifdef
138
139bool Object::IsSeqString() {
140 if (!IsString()) return false;
141 return StringShape(String::cast(this)).IsSequential();
142}
143
144
145bool Object::IsSeqAsciiString() {
146 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000147 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000148 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000149}
150
151
152bool Object::IsSeqTwoByteString() {
153 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000154 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000155 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000156}
157
158
159bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000160 if (!IsString()) return false;
161 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000162}
163
164
165bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000166 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000167 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000168 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000169}
170
171
172bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000173 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000174 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000175 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000176}
177
178
ager@chromium.org870a0b62008-11-04 11:43:05 +0000179bool Object::IsSlicedString() {
180 if (!IsString()) return false;
181 return StringShape(String::cast(this)).IsSliced();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000182}
183
184
ager@chromium.org870a0b62008-11-04 11:43:05 +0000185#endif // DEBUG
186
187
188StringShape::StringShape(String* str)
189 : type_(str->map()->instance_type()) {
190 set_valid();
191 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000192}
193
194
ager@chromium.org870a0b62008-11-04 11:43:05 +0000195StringShape::StringShape(Map* map)
196 : type_(map->instance_type()) {
197 set_valid();
198 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000199}
200
201
ager@chromium.org870a0b62008-11-04 11:43:05 +0000202StringShape::StringShape(InstanceType t)
203 : type_(static_cast<uint32_t>(t)) {
204 set_valid();
205 ASSERT((type_ & kIsNotStringMask) == kStringTag);
206}
207
208
209bool StringShape::IsSymbol() {
210 ASSERT(valid());
211 return (type_ & kIsSymbolMask) == kSymbolTag;
212}
213
214
ager@chromium.org5ec48922009-05-05 07:25:34 +0000215bool String::IsAsciiRepresentation() {
216 uint32_t type = map()->instance_type();
217 if ((type & kStringRepresentationMask) == kSlicedStringTag) {
218 return SlicedString::cast(this)->buffer()->IsAsciiRepresentation();
219 }
220 if ((type & kStringRepresentationMask) == kConsStringTag &&
221 ConsString::cast(this)->second()->length() == 0) {
222 return ConsString::cast(this)->first()->IsAsciiRepresentation();
223 }
224 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000225}
226
227
ager@chromium.org5ec48922009-05-05 07:25:34 +0000228bool String::IsTwoByteRepresentation() {
229 uint32_t type = map()->instance_type();
230 if ((type & kStringRepresentationMask) == kSlicedStringTag) {
231 return SlicedString::cast(this)->buffer()->IsTwoByteRepresentation();
232 } else if ((type & kStringRepresentationMask) == kConsStringTag &&
233 ConsString::cast(this)->second()->length() == 0) {
234 return ConsString::cast(this)->first()->IsTwoByteRepresentation();
235 }
236 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000237}
238
239
240bool StringShape::IsCons() {
241 return (type_ & kStringRepresentationMask) == kConsStringTag;
242}
243
244
245bool StringShape::IsSliced() {
246 return (type_ & kStringRepresentationMask) == kSlicedStringTag;
247}
248
249
250bool StringShape::IsExternal() {
251 return (type_ & kStringRepresentationMask) == kExternalStringTag;
252}
253
254
255bool StringShape::IsSequential() {
256 return (type_ & kStringRepresentationMask) == kSeqStringTag;
257}
258
259
260StringRepresentationTag StringShape::representation_tag() {
261 uint32_t tag = (type_ & kStringRepresentationMask);
262 return static_cast<StringRepresentationTag>(tag);
263}
264
265
266uint32_t StringShape::full_representation_tag() {
267 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
268}
269
270
271uint32_t StringShape::size_tag() {
272 return (type_ & kStringSizeMask);
273}
274
275
276bool StringShape::IsSequentialAscii() {
277 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
278}
279
280
281bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000282 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000283}
284
285
286bool StringShape::IsExternalAscii() {
287 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
288}
289
290
291bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000292 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000293}
294
295
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000296uc32 FlatStringReader::Get(int index) {
297 ASSERT(0 <= index && index <= length_);
298 if (is_ascii_) {
299 return static_cast<const byte*>(start_)[index];
300 } else {
301 return static_cast<const uc16*>(start_)[index];
302 }
303}
304
305
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000306bool Object::IsNumber() {
307 return IsSmi() || IsHeapNumber();
308}
309
310
311bool Object::IsByteArray() {
312 return Object::IsHeapObject()
313 && HeapObject::cast(this)->map()->instance_type() == BYTE_ARRAY_TYPE;
314}
315
316
317bool Object::IsFailure() {
318 return HAS_FAILURE_TAG(this);
319}
320
321
322bool Object::IsRetryAfterGC() {
323 return HAS_FAILURE_TAG(this)
324 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
325}
326
327
ager@chromium.org7c537e22008-10-16 08:43:32 +0000328bool Object::IsOutOfMemoryFailure() {
329 return HAS_FAILURE_TAG(this)
330 && Failure::cast(this)->IsOutOfMemoryException();
331}
332
333
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000334bool Object::IsException() {
335 return this == Failure::Exception();
336}
337
338
339bool Object::IsJSObject() {
340 return IsHeapObject()
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000341 && HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000342}
343
344
ager@chromium.org32912102009-01-16 10:38:43 +0000345bool Object::IsJSContextExtensionObject() {
346 return IsHeapObject()
347 && (HeapObject::cast(this)->map()->instance_type() ==
348 JS_CONTEXT_EXTENSION_OBJECT_TYPE);
349}
350
351
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000352bool Object::IsMap() {
353 return Object::IsHeapObject()
354 && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE;
355}
356
357
358bool Object::IsFixedArray() {
359 return Object::IsHeapObject()
360 && HeapObject::cast(this)->map()->instance_type() == FIXED_ARRAY_TYPE;
361}
362
363
364bool Object::IsDescriptorArray() {
365 return IsFixedArray();
366}
367
368
369bool Object::IsContext() {
370 return Object::IsHeapObject()
371 && (HeapObject::cast(this)->map() == Heap::context_map() ||
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000372 HeapObject::cast(this)->map() == Heap::catch_context_map() ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000373 HeapObject::cast(this)->map() == Heap::global_context_map());
374}
375
376
christian.plesner.hansen@gmail.com37abdec2009-01-06 14:43:28 +0000377bool Object::IsCatchContext() {
378 return Object::IsHeapObject()
379 && HeapObject::cast(this)->map() == Heap::catch_context_map();
380}
381
382
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000383bool Object::IsGlobalContext() {
384 return Object::IsHeapObject()
385 && HeapObject::cast(this)->map() == Heap::global_context_map();
386}
387
388
389bool Object::IsJSFunction() {
390 return Object::IsHeapObject()
391 && HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_TYPE;
392}
393
394
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000395template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000396 return obj->IsJSFunction();
397}
398
399
400bool Object::IsCode() {
401 return Object::IsHeapObject()
402 && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE;
403}
404
405
406bool Object::IsOddball() {
407 return Object::IsHeapObject()
408 && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE;
409}
410
411
412bool Object::IsSharedFunctionInfo() {
413 return Object::IsHeapObject() &&
414 (HeapObject::cast(this)->map()->instance_type() ==
415 SHARED_FUNCTION_INFO_TYPE);
416}
417
418
419bool Object::IsJSValue() {
420 return Object::IsHeapObject()
421 && HeapObject::cast(this)->map()->instance_type() == JS_VALUE_TYPE;
422}
423
424
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000425bool Object::IsStringWrapper() {
426 return IsJSValue() && JSValue::cast(this)->value()->IsString();
427}
428
429
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000430bool Object::IsProxy() {
431 return Object::IsHeapObject()
432 && HeapObject::cast(this)->map()->instance_type() == PROXY_TYPE;
433}
434
435
436bool Object::IsBoolean() {
437 return IsTrue() || IsFalse();
438}
439
440
441bool Object::IsJSArray() {
442 return Object::IsHeapObject()
443 && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;
444}
445
446
ager@chromium.org236ad962008-09-25 09:45:57 +0000447bool Object::IsJSRegExp() {
448 return Object::IsHeapObject()
449 && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
450}
451
452
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000453template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000454 return obj->IsJSArray();
455}
456
457
458bool Object::IsHashTable() {
459 return Object::IsHeapObject()
460 && HeapObject::cast(this)->map() == Heap::hash_table_map();
461}
462
463
464bool Object::IsDictionary() {
465 return IsHashTable() && this != Heap::symbol_table();
466}
467
468
469bool Object::IsSymbolTable() {
470 return IsHashTable() && this == Heap::symbol_table();
471}
472
473
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000474bool Object::IsCompilationCacheTable() {
475 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000476}
477
478
ager@chromium.org236ad962008-09-25 09:45:57 +0000479bool Object::IsMapCache() {
480 return IsHashTable();
481}
482
483
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000484bool Object::IsPrimitive() {
485 return IsOddball() || IsNumber() || IsString();
486}
487
488
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000489bool Object::IsJSGlobalProxy() {
490 bool result = IsHeapObject() &&
491 (HeapObject::cast(this)->map()->instance_type() ==
492 JS_GLOBAL_PROXY_TYPE);
493 ASSERT(!result || IsAccessCheckNeeded());
494 return result;
495}
496
497
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000498bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000499 if (!IsHeapObject()) return false;
500
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000501 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000502 return type == JS_GLOBAL_OBJECT_TYPE ||
503 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000504}
505
506
507bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000508 return IsHeapObject() &&
509 (HeapObject::cast(this)->map()->instance_type() ==
510 JS_GLOBAL_OBJECT_TYPE);
511}
512
513
514bool Object::IsJSBuiltinsObject() {
515 return IsHeapObject() &&
516 (HeapObject::cast(this)->map()->instance_type() ==
517 JS_BUILTINS_OBJECT_TYPE);
518}
519
520
521bool Object::IsUndetectableObject() {
522 return IsHeapObject()
523 && HeapObject::cast(this)->map()->is_undetectable();
524}
525
526
527bool Object::IsAccessCheckNeeded() {
528 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000529 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000530}
531
532
533bool Object::IsStruct() {
534 if (!IsHeapObject()) return false;
535 switch (HeapObject::cast(this)->map()->instance_type()) {
536#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
537 STRUCT_LIST(MAKE_STRUCT_CASE)
538#undef MAKE_STRUCT_CASE
539 default: return false;
540 }
541}
542
543
544#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
545 bool Object::Is##Name() { \
546 return Object::IsHeapObject() \
547 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
548 }
549 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
550#undef MAKE_STRUCT_PREDICATE
551
552
553bool Object::IsUndefined() {
554 return this == Heap::undefined_value();
555}
556
557
558bool Object::IsTheHole() {
559 return this == Heap::the_hole_value();
560}
561
562
563bool Object::IsNull() {
564 return this == Heap::null_value();
565}
566
567
568bool Object::IsTrue() {
569 return this == Heap::true_value();
570}
571
572
573bool Object::IsFalse() {
574 return this == Heap::false_value();
575}
576
577
578double Object::Number() {
579 ASSERT(IsNumber());
580 return IsSmi()
581 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
582 : reinterpret_cast<HeapNumber*>(this)->value();
583}
584
585
586
587Object* Object::ToSmi() {
588 if (IsSmi()) return this;
589 if (IsHeapNumber()) {
590 double value = HeapNumber::cast(this)->value();
591 int int_value = FastD2I(value);
592 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
593 return Smi::FromInt(int_value);
594 }
595 }
596 return Failure::Exception();
597}
598
599
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000600bool Object::HasSpecificClassOf(String* name) {
601 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
602}
603
604
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000605Object* Object::GetElement(uint32_t index) {
606 return GetElementWithReceiver(this, index);
607}
608
609
610Object* Object::GetProperty(String* key) {
611 PropertyAttributes attributes;
612 return GetPropertyWithReceiver(this, key, &attributes);
613}
614
615
616Object* Object::GetProperty(String* key, PropertyAttributes* attributes) {
617 return GetPropertyWithReceiver(this, key, attributes);
618}
619
620
621#define FIELD_ADDR(p, offset) \
622 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
623
624#define READ_FIELD(p, offset) \
625 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
626
627#define WRITE_FIELD(p, offset, value) \
628 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
629
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000630
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000631#define WRITE_BARRIER(object, offset) \
632 Heap::RecordWrite(object->address(), offset);
633
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000634// CONDITIONAL_WRITE_BARRIER must be issued after the actual
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000635// write due to the assert validating the written value.
636#define CONDITIONAL_WRITE_BARRIER(object, offset, mode) \
637 if (mode == UPDATE_WRITE_BARRIER) { \
638 Heap::RecordWrite(object->address(), offset); \
639 } else { \
640 ASSERT(mode == SKIP_WRITE_BARRIER); \
641 ASSERT(Heap::InNewSpace(object) || \
642 !Heap::InNewSpace(READ_FIELD(object, offset))); \
643 }
644
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000645#define READ_DOUBLE_FIELD(p, offset) \
646 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
647
648#define WRITE_DOUBLE_FIELD(p, offset, value) \
649 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
650
651#define READ_INT_FIELD(p, offset) \
652 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
653
654#define WRITE_INT_FIELD(p, offset, value) \
655 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
656
ager@chromium.org7c537e22008-10-16 08:43:32 +0000657#define READ_UINT32_FIELD(p, offset) \
658 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
659
660#define WRITE_UINT32_FIELD(p, offset, value) \
661 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
662
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000663#define READ_SHORT_FIELD(p, offset) \
664 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
665
666#define WRITE_SHORT_FIELD(p, offset, value) \
667 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
668
669#define READ_BYTE_FIELD(p, offset) \
670 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
671
672#define WRITE_BYTE_FIELD(p, offset, value) \
673 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
674
675
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000676Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
677 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000678}
679
680
681int Smi::value() {
ager@chromium.org5ec48922009-05-05 07:25:34 +0000682 return static_cast<int>(reinterpret_cast<intptr_t>(this) >> kSmiTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000683}
684
685
686Smi* Smi::FromInt(int value) {
687 ASSERT(Smi::IsValid(value));
ager@chromium.org9085a012009-05-11 19:22:57 +0000688 intptr_t tagged_value =
689 (static_cast<intptr_t>(value) << kSmiTagSize) | kSmiTag;
690 return reinterpret_cast<Smi*>(tagged_value);
691}
692
693
694Smi* Smi::FromIntptr(intptr_t value) {
695 ASSERT(Smi::IsValid(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000696 return reinterpret_cast<Smi*>((value << kSmiTagSize) | kSmiTag);
697}
698
699
700Failure::Type Failure::type() const {
701 return static_cast<Type>(value() & kFailureTypeTagMask);
702}
703
704
705bool Failure::IsInternalError() const {
706 return type() == INTERNAL_ERROR;
707}
708
709
710bool Failure::IsOutOfMemoryException() const {
711 return type() == OUT_OF_MEMORY_EXCEPTION;
712}
713
714
715int Failure::requested() const {
716 const int kShiftBits =
717 kFailureTypeTagSize + kSpaceTagSize - kObjectAlignmentBits;
718 STATIC_ASSERT(kShiftBits >= 0);
719 ASSERT(type() == RETRY_AFTER_GC);
720 return value() >> kShiftBits;
721}
722
723
724AllocationSpace Failure::allocation_space() const {
725 ASSERT_EQ(RETRY_AFTER_GC, type());
726 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
727 & kSpaceTagMask);
728}
729
730
731Failure* Failure::InternalError() {
732 return Construct(INTERNAL_ERROR);
733}
734
735
736Failure* Failure::Exception() {
737 return Construct(EXCEPTION);
738}
739
740Failure* Failure::OutOfMemoryException() {
741 return Construct(OUT_OF_MEMORY_EXCEPTION);
742}
743
744
745int Failure::value() const {
ager@chromium.org5ec48922009-05-05 07:25:34 +0000746 return static_cast<int>(reinterpret_cast<intptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000747}
748
749
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000750Failure* Failure::RetryAfterGC(int requested_bytes) {
751 int requested = requested_bytes >> kObjectAlignmentBits;
752 int value = (requested << kSpaceTagSize) | NEW_SPACE;
753 ASSERT(value >> kSpaceTagSize == requested);
754 ASSERT(Smi::IsValid(value));
755 ASSERT(value == ((value << kFailureTypeTagSize) >> kFailureTypeTagSize));
756 ASSERT(Smi::IsValid(value << kFailureTypeTagSize));
757 return Construct(RETRY_AFTER_GC, value);
758}
759
760
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000761Failure* Failure::Construct(Type type, int value) {
762 int info = (value << kFailureTypeTagSize) | type;
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000763 // TODO(X64): Stop using Smi validation for non-smi checks, even if they
764 // happen to be identical at the moment.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000765 ASSERT(Smi::IsValid(info)); // Same validation check as in Smi
ager@chromium.org5ec48922009-05-05 07:25:34 +0000766 return reinterpret_cast<Failure*>(
kasperl@chromium.org71affb52009-05-26 05:44:31 +0000767 (static_cast<intptr_t>(info) << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000768}
769
770
771bool Smi::IsValid(int value) {
772#ifdef DEBUG
773 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
774#endif
775 // To be representable as an tagged small integer, the two
776 // most-significant bits of 'value' must be either 00 or 11 due to
777 // sign-extension. To check this we add 01 to the two
778 // most-significant bits, and check if the most-significant bit is 0
779 //
780 // CAUTION: The original code below:
781 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
782 // may lead to incorrect results according to the C language spec, and
783 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
784 // compiler may produce undefined results in case of signed integer
785 // overflow. The computation must be done w/ unsigned ints.
786 bool result =
787 ((static_cast<unsigned int>(value) + 0x40000000U) & 0x80000000U) == 0;
788 ASSERT(result == in_range);
789 return result;
790}
791
792
ager@chromium.org9085a012009-05-11 19:22:57 +0000793bool Smi::IsIntptrValid(intptr_t value) {
794#ifdef DEBUG
795 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
796#endif
797 // See Smi::IsValid(int) for description.
798 bool result =
799 ((static_cast<uintptr_t>(value) + 0x40000000U) < 0x80000000U);
800 ASSERT(result == in_range);
801 return result;
802}
803
804
kasper.lund7276f142008-07-30 08:49:36 +0000805MapWord MapWord::FromMap(Map* map) {
806 return MapWord(reinterpret_cast<uintptr_t>(map));
807}
808
809
810Map* MapWord::ToMap() {
811 return reinterpret_cast<Map*>(value_);
812}
813
814
815bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000816 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000817}
818
819
820MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000821 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
822 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +0000823}
824
825
826HeapObject* MapWord::ToForwardingAddress() {
827 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +0000828 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +0000829}
830
831
832bool MapWord::IsMarked() {
833 return (value_ & kMarkingMask) == 0;
834}
835
836
837void MapWord::SetMark() {
838 value_ &= ~kMarkingMask;
839}
840
841
842void MapWord::ClearMark() {
843 value_ |= kMarkingMask;
844}
845
846
847bool MapWord::IsOverflowed() {
848 return (value_ & kOverflowMask) != 0;
849}
850
851
852void MapWord::SetOverflow() {
853 value_ |= kOverflowMask;
854}
855
856
857void MapWord::ClearOverflow() {
858 value_ &= ~kOverflowMask;
859}
860
861
862MapWord MapWord::EncodeAddress(Address map_address, int offset) {
863 // Offset is the distance in live bytes from the first live object in the
864 // same page. The offset between two objects in the same page should not
865 // exceed the object area size of a page.
866 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
867
868 int compact_offset = offset >> kObjectAlignmentBits;
869 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
870
871 Page* map_page = Page::FromAddress(map_address);
872 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
873
874 int map_page_offset =
875 map_page->Offset(map_address) >> kObjectAlignmentBits;
876
877 uintptr_t encoding =
878 (compact_offset << kForwardingOffsetShift) |
879 (map_page_offset << kMapPageOffsetShift) |
880 (map_page->mc_page_index << kMapPageIndexShift);
881 return MapWord(encoding);
882}
883
884
885Address MapWord::DecodeMapAddress(MapSpace* map_space) {
886 int map_page_index = (value_ & kMapPageIndexMask) >> kMapPageIndexShift;
887 ASSERT_MAP_PAGE_INDEX(map_page_index);
888
889 int map_page_offset =
890 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift)
891 << kObjectAlignmentBits;
892
893 return (map_space->PageAddress(map_page_index) + map_page_offset);
894}
895
896
897int MapWord::DecodeOffset() {
898 // The offset field is represented in the kForwardingOffsetBits
899 // most-significant bits.
900 int offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
901 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
902 return offset;
903}
904
905
906MapWord MapWord::FromEncodedAddress(Address address) {
907 return MapWord(reinterpret_cast<uintptr_t>(address));
908}
909
910
911Address MapWord::ToEncodedAddress() {
912 return reinterpret_cast<Address>(value_);
913}
914
915
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000916#ifdef DEBUG
917void HeapObject::VerifyObjectField(int offset) {
918 VerifyPointer(READ_FIELD(this, offset));
919}
920#endif
921
922
923Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +0000924 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000925}
926
927
928void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +0000929 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000930}
931
932
kasper.lund7276f142008-07-30 08:49:36 +0000933MapWord HeapObject::map_word() {
934 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
935}
936
937
938void HeapObject::set_map_word(MapWord map_word) {
939 // WRITE_FIELD does not update the remembered set, but there is no need
940 // here.
941 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
942}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000943
944
945HeapObject* HeapObject::FromAddress(Address address) {
946 ASSERT_TAG_ALIGNED(address);
947 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
948}
949
950
951Address HeapObject::address() {
952 return reinterpret_cast<Address>(this) - kHeapObjectTag;
953}
954
955
956int HeapObject::Size() {
957 return SizeFromMap(map());
958}
959
960
961void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
962 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
963 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
964}
965
966
967void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
968 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
969}
970
971
kasper.lund7276f142008-07-30 08:49:36 +0000972bool HeapObject::IsMarked() {
973 return map_word().IsMarked();
974}
975
976
977void HeapObject::SetMark() {
978 ASSERT(!IsMarked());
979 MapWord first_word = map_word();
980 first_word.SetMark();
981 set_map_word(first_word);
982}
983
984
985void HeapObject::ClearMark() {
986 ASSERT(IsMarked());
987 MapWord first_word = map_word();
988 first_word.ClearMark();
989 set_map_word(first_word);
990}
991
992
993bool HeapObject::IsOverflowed() {
994 return map_word().IsOverflowed();
995}
996
997
998void HeapObject::SetOverflow() {
999 MapWord first_word = map_word();
1000 first_word.SetOverflow();
1001 set_map_word(first_word);
1002}
1003
1004
1005void HeapObject::ClearOverflow() {
1006 ASSERT(IsOverflowed());
1007 MapWord first_word = map_word();
1008 first_word.ClearOverflow();
1009 set_map_word(first_word);
1010}
1011
1012
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001013double HeapNumber::value() {
1014 return READ_DOUBLE_FIELD(this, kValueOffset);
1015}
1016
1017
1018void HeapNumber::set_value(double value) {
1019 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1020}
1021
1022
1023ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001024ACCESSORS(JSObject, elements, FixedArray, kElementsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001025
1026
1027void JSObject::initialize_properties() {
1028 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1029 WRITE_FIELD(this, kPropertiesOffset, Heap::empty_fixed_array());
1030}
1031
1032
1033void JSObject::initialize_elements() {
1034 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
1035 WRITE_FIELD(this, kElementsOffset, Heap::empty_fixed_array());
1036}
1037
1038
1039ACCESSORS(Oddball, to_string, String, kToStringOffset)
1040ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1041
1042
1043int JSObject::GetHeaderSize() {
1044 switch (map()->instance_type()) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001045 case JS_GLOBAL_PROXY_TYPE:
1046 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001047 case JS_GLOBAL_OBJECT_TYPE:
1048 return JSGlobalObject::kSize;
1049 case JS_BUILTINS_OBJECT_TYPE:
1050 return JSBuiltinsObject::kSize;
1051 case JS_FUNCTION_TYPE:
1052 return JSFunction::kSize;
1053 case JS_VALUE_TYPE:
1054 return JSValue::kSize;
1055 case JS_ARRAY_TYPE:
1056 return JSValue::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001057 case JS_REGEXP_TYPE:
1058 return JSValue::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001059 case JS_OBJECT_TYPE:
ager@chromium.org32912102009-01-16 10:38:43 +00001060 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001061 return JSObject::kHeaderSize;
1062 default:
1063 UNREACHABLE();
1064 return 0;
1065 }
1066}
1067
1068
1069int JSObject::GetInternalFieldCount() {
1070 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001071 // Make sure to adjust for the number of in-object properties. These
1072 // properties do contribute to the size, but are not internal fields.
1073 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1074 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001075}
1076
1077
1078Object* JSObject::GetInternalField(int index) {
1079 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001080 // Internal objects do follow immediately after the header, whereas in-object
1081 // properties are at the end of the object. Therefore there is no need
1082 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001083 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1084}
1085
1086
1087void JSObject::SetInternalField(int index, Object* value) {
1088 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001089 // Internal objects do follow immediately after the header, whereas in-object
1090 // properties are at the end of the object. Therefore there is no need
1091 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001092 int offset = GetHeaderSize() + (kPointerSize * index);
1093 WRITE_FIELD(this, offset, value);
1094 WRITE_BARRIER(this, offset);
1095}
1096
1097
ager@chromium.org7c537e22008-10-16 08:43:32 +00001098// Access fast-case object properties at index. The use of these routines
1099// is needed to correctly distinguish between properties stored in-object and
1100// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001101Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001102 // Adjust for the number of properties stored in the object.
1103 index -= map()->inobject_properties();
1104 if (index < 0) {
1105 int offset = map()->instance_size() + (index * kPointerSize);
1106 return READ_FIELD(this, offset);
1107 } else {
1108 ASSERT(index < properties()->length());
1109 return properties()->get(index);
1110 }
1111}
1112
1113
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001114Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001115 // Adjust for the number of properties stored in the object.
1116 index -= map()->inobject_properties();
1117 if (index < 0) {
1118 int offset = map()->instance_size() + (index * kPointerSize);
1119 WRITE_FIELD(this, offset, value);
1120 WRITE_BARRIER(this, offset);
1121 } else {
1122 ASSERT(index < properties()->length());
1123 properties()->set(index, value);
1124 }
1125 return value;
1126}
1127
1128
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001129Object* JSObject::InObjectPropertyAt(int index) {
1130 // Adjust for the number of properties stored in the object.
1131 index -= map()->inobject_properties();
1132 ASSERT(index < 0);
1133 int offset = map()->instance_size() + (index * kPointerSize);
1134 return READ_FIELD(this, offset);
1135}
1136
1137
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001138Object* JSObject::InObjectPropertyAtPut(int index,
1139 Object* value,
1140 WriteBarrierMode mode) {
1141 // Adjust for the number of properties stored in the object.
1142 index -= map()->inobject_properties();
1143 ASSERT(index < 0);
1144 int offset = map()->instance_size() + (index * kPointerSize);
1145 WRITE_FIELD(this, offset, value);
1146 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
1147 return value;
1148}
1149
1150
1151
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001152void JSObject::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001153 Object* value = Heap::undefined_value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001154 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001155 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001156 }
1157}
1158
1159
1160void Struct::InitializeBody(int object_size) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001161 Object* value = Heap::undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001162 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001163 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001164 }
1165}
1166
1167
1168bool JSObject::HasFastProperties() {
1169 return !properties()->IsDictionary();
1170}
1171
1172
1173bool Array::IndexFromObject(Object* object, uint32_t* index) {
1174 if (object->IsSmi()) {
1175 int value = Smi::cast(object)->value();
1176 if (value < 0) return false;
1177 *index = value;
1178 return true;
1179 }
1180 if (object->IsHeapNumber()) {
1181 double value = HeapNumber::cast(object)->value();
1182 uint32_t uint_value = static_cast<uint32_t>(value);
1183 if (value == static_cast<double>(uint_value)) {
1184 *index = uint_value;
1185 return true;
1186 }
1187 }
1188 return false;
1189}
1190
1191
1192bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1193 if (!this->IsJSValue()) return false;
1194
1195 JSValue* js_value = JSValue::cast(this);
1196 if (!js_value->value()->IsString()) return false;
1197
1198 String* str = String::cast(js_value->value());
1199 if (index >= (uint32_t)str->length()) return false;
1200
1201 return true;
1202}
1203
1204
1205Object* FixedArray::get(int index) {
1206 ASSERT(index >= 0 && index < this->length());
1207 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1208}
1209
1210
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001211void FixedArray::set(int index, Smi* value) {
1212 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1213 int offset = kHeaderSize + index * kPointerSize;
1214 WRITE_FIELD(this, offset, value);
1215}
1216
1217
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001218void FixedArray::set(int index, Object* value) {
1219 ASSERT(index >= 0 && index < this->length());
1220 int offset = kHeaderSize + index * kPointerSize;
1221 WRITE_FIELD(this, offset, value);
1222 WRITE_BARRIER(this, offset);
1223}
1224
1225
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001226WriteBarrierMode HeapObject::GetWriteBarrierMode() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001227 if (Heap::InNewSpace(this)) return SKIP_WRITE_BARRIER;
1228 return UPDATE_WRITE_BARRIER;
1229}
1230
1231
1232void FixedArray::set(int index,
1233 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001234 WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001235 ASSERT(index >= 0 && index < this->length());
1236 int offset = kHeaderSize + index * kPointerSize;
1237 WRITE_FIELD(this, offset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001238 CONDITIONAL_WRITE_BARRIER(this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001239}
1240
1241
1242void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
1243 ASSERT(index >= 0 && index < array->length());
1244 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1245}
1246
1247
1248void FixedArray::set_undefined(int index) {
1249 ASSERT(index >= 0 && index < this->length());
1250 ASSERT(!Heap::InNewSpace(Heap::undefined_value()));
1251 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
1252 Heap::undefined_value());
1253}
1254
1255
ager@chromium.org236ad962008-09-25 09:45:57 +00001256void FixedArray::set_null(int index) {
1257 ASSERT(index >= 0 && index < this->length());
1258 ASSERT(!Heap::InNewSpace(Heap::null_value()));
1259 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::null_value());
1260}
1261
1262
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001263void FixedArray::set_the_hole(int index) {
1264 ASSERT(index >= 0 && index < this->length());
1265 ASSERT(!Heap::InNewSpace(Heap::the_hole_value()));
1266 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, Heap::the_hole_value());
1267}
1268
1269
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001270bool DescriptorArray::IsEmpty() {
1271 ASSERT(this == Heap::empty_descriptor_array() ||
1272 this->length() > 2);
1273 return this == Heap::empty_descriptor_array();
1274}
1275
1276
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001277void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1278 Object* tmp = array->get(first);
1279 fast_set(array, first, array->get(second));
1280 fast_set(array, second, tmp);
1281}
1282
1283
1284int DescriptorArray::Search(String* name) {
1285 SLOW_ASSERT(IsSortedNoDuplicates());
1286
1287 // Check for empty descriptor array.
1288 int nof = number_of_descriptors();
1289 if (nof == 0) return kNotFound;
1290
1291 // Fast case: do linear search for small arrays.
1292 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001293 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001294 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001295 }
1296
1297 // Slow case: perform binary search.
1298 return BinarySearch(name, 0, nof - 1);
1299}
1300
1301
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001302String* DescriptorArray::GetKey(int descriptor_number) {
1303 ASSERT(descriptor_number < number_of_descriptors());
1304 return String::cast(get(ToKeyIndex(descriptor_number)));
1305}
1306
1307
1308Object* DescriptorArray::GetValue(int descriptor_number) {
1309 ASSERT(descriptor_number < number_of_descriptors());
1310 return GetContentArray()->get(ToValueIndex(descriptor_number));
1311}
1312
1313
1314Smi* DescriptorArray::GetDetails(int descriptor_number) {
1315 ASSERT(descriptor_number < number_of_descriptors());
1316 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1317}
1318
1319
1320void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1321 desc->Init(GetKey(descriptor_number),
1322 GetValue(descriptor_number),
1323 GetDetails(descriptor_number));
1324}
1325
1326
1327void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1328 // Range check.
1329 ASSERT(descriptor_number < number_of_descriptors());
1330
1331 // Make sure non of the elements in desc are in new space.
1332 ASSERT(!Heap::InNewSpace(desc->GetKey()));
1333 ASSERT(!Heap::InNewSpace(desc->GetValue()));
1334
1335 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1336 FixedArray* content_array = GetContentArray();
1337 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1338 fast_set(content_array, ToDetailsIndex(descriptor_number),
1339 desc->GetDetails().AsSmi());
1340}
1341
1342
1343void DescriptorArray::Swap(int first, int second) {
1344 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1345 FixedArray* content_array = GetContentArray();
1346 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1347 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1348}
1349
1350
1351bool Dictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001352 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001353 if (!max_index_object->IsSmi()) return false;
1354 return 0 !=
1355 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1356}
1357
1358
1359uint32_t Dictionary::max_number_key() {
1360 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001361 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001362 if (!max_index_object->IsSmi()) return 0;
1363 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
1364 return value >> kRequiresSlowElementsTagSize;
1365}
1366
1367
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001368void Dictionary::set_requires_slow_elements() {
1369 set(kMaxNumberKeyIndex,
1370 Smi::FromInt(kRequiresSlowElementsMask),
1371 SKIP_WRITE_BARRIER);
1372}
1373
1374
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001375// ------------------------------------
1376// Cast operations
1377
1378
1379CAST_ACCESSOR(FixedArray)
1380CAST_ACCESSOR(DescriptorArray)
1381CAST_ACCESSOR(Dictionary)
1382CAST_ACCESSOR(SymbolTable)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00001383CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00001384CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001385CAST_ACCESSOR(String)
1386CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00001387CAST_ACCESSOR(SeqAsciiString)
1388CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001389CAST_ACCESSOR(ConsString)
1390CAST_ACCESSOR(SlicedString)
1391CAST_ACCESSOR(ExternalString)
1392CAST_ACCESSOR(ExternalAsciiString)
1393CAST_ACCESSOR(ExternalTwoByteString)
1394CAST_ACCESSOR(JSObject)
1395CAST_ACCESSOR(Smi)
1396CAST_ACCESSOR(Failure)
1397CAST_ACCESSOR(HeapObject)
1398CAST_ACCESSOR(HeapNumber)
1399CAST_ACCESSOR(Oddball)
1400CAST_ACCESSOR(SharedFunctionInfo)
1401CAST_ACCESSOR(Map)
1402CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001403CAST_ACCESSOR(GlobalObject)
1404CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001405CAST_ACCESSOR(JSGlobalObject)
1406CAST_ACCESSOR(JSBuiltinsObject)
1407CAST_ACCESSOR(Code)
1408CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00001409CAST_ACCESSOR(JSRegExp)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001410CAST_ACCESSOR(Proxy)
1411CAST_ACCESSOR(ByteArray)
1412CAST_ACCESSOR(Struct)
1413
1414
1415#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
1416 STRUCT_LIST(MAKE_STRUCT_CAST)
1417#undef MAKE_STRUCT_CAST
1418
1419template <int prefix_size, int elem_size>
1420HashTable<prefix_size, elem_size>* HashTable<prefix_size, elem_size>::cast(
1421 Object* obj) {
1422 ASSERT(obj->IsHashTable());
1423 return reinterpret_cast<HashTable*>(obj);
1424}
1425
1426
1427INT_ACCESSORS(Array, length, kLengthOffset)
1428
1429
1430bool String::Equals(String* other) {
1431 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001432 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
1433 return false;
1434 }
1435 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001436}
1437
1438
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001439int String::length() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001440 uint32_t len = READ_INT_FIELD(this, kLengthOffset);
1441
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001442 ASSERT(kShortStringTag + kLongLengthShift == kShortLengthShift);
1443 ASSERT(kMediumStringTag + kLongLengthShift == kMediumLengthShift);
1444 ASSERT(kLongStringTag == 0);
1445
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001446 return len >> (StringShape(this).size_tag() + kLongLengthShift);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001447}
1448
1449
1450void String::set_length(int value) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001451 ASSERT(kShortStringTag + kLongLengthShift == kShortLengthShift);
1452 ASSERT(kMediumStringTag + kLongLengthShift == kMediumLengthShift);
1453 ASSERT(kLongStringTag == 0);
1454
1455 WRITE_INT_FIELD(this,
1456 kLengthOffset,
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001457 value << (StringShape(this).size_tag() + kLongLengthShift));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001458}
1459
1460
ager@chromium.org7c537e22008-10-16 08:43:32 +00001461uint32_t String::length_field() {
1462 return READ_UINT32_FIELD(this, kLengthOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001463}
1464
1465
ager@chromium.org7c537e22008-10-16 08:43:32 +00001466void String::set_length_field(uint32_t value) {
1467 WRITE_UINT32_FIELD(this, kLengthOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001468}
1469
1470
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001471Object* String::TryFlattenIfNotFlat() {
ager@chromium.org236ad962008-09-25 09:45:57 +00001472 // We don't need to flatten strings that are already flat. Since this code
1473 // is inlined, it can be helpful in the flat case to not call out to Flatten.
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001474 if (!IsFlat()) {
1475 return TryFlatten();
ager@chromium.org236ad962008-09-25 09:45:57 +00001476 }
ager@chromium.orgddb913d2009-01-27 10:01:48 +00001477 return this;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001478}
1479
1480
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001481uint16_t String::Get(int index) {
1482 ASSERT(index >= 0 && index < length());
1483 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001484 case kSeqStringTag | kAsciiStringTag:
1485 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
1486 case kSeqStringTag | kTwoByteStringTag:
1487 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
1488 case kConsStringTag | kAsciiStringTag:
1489 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001490 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00001491 case kSlicedStringTag | kAsciiStringTag:
1492 case kSlicedStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001493 return SlicedString::cast(this)->SlicedStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00001494 case kExternalStringTag | kAsciiStringTag:
1495 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
1496 case kExternalStringTag | kTwoByteStringTag:
1497 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001498 default:
1499 break;
1500 }
1501
1502 UNREACHABLE();
1503 return 0;
1504}
1505
1506
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001507void String::Set(int index, uint16_t value) {
1508 ASSERT(index >= 0 && index < length());
1509 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001510
ager@chromium.org5ec48922009-05-05 07:25:34 +00001511 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00001512 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
1513 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001514}
1515
1516
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001517bool String::IsFlat() {
1518 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00001519 case kConsStringTag: {
1520 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00001521 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00001522 return second->length() == 0;
1523 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00001524 case kSlicedStringTag: {
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001525 StringRepresentationTag tag =
1526 StringShape(SlicedString::cast(this)->buffer()).representation_tag();
ager@chromium.org7c537e22008-10-16 08:43:32 +00001527 return tag == kSeqStringTag || tag == kExternalStringTag;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001528 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00001529 default:
1530 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001531 }
1532}
1533
1534
ager@chromium.org7c537e22008-10-16 08:43:32 +00001535uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001536 ASSERT(index >= 0 && index < length());
1537 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1538}
1539
1540
ager@chromium.org7c537e22008-10-16 08:43:32 +00001541void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001542 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
1543 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
1544 static_cast<byte>(value));
1545}
1546
1547
ager@chromium.org7c537e22008-10-16 08:43:32 +00001548Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001549 return FIELD_ADDR(this, kHeaderSize);
1550}
1551
1552
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001553char* SeqAsciiString::GetChars() {
1554 return reinterpret_cast<char*>(GetCharsAddress());
1555}
1556
1557
ager@chromium.org7c537e22008-10-16 08:43:32 +00001558Address SeqTwoByteString::GetCharsAddress() {
1559 return FIELD_ADDR(this, kHeaderSize);
1560}
1561
1562
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001563uc16* SeqTwoByteString::GetChars() {
1564 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
1565}
1566
1567
ager@chromium.org7c537e22008-10-16 08:43:32 +00001568uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001569 ASSERT(index >= 0 && index < length());
1570 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
1571}
1572
1573
ager@chromium.org7c537e22008-10-16 08:43:32 +00001574void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001575 ASSERT(index >= 0 && index < length());
1576 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
1577}
1578
1579
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001580int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001581 uint32_t length = READ_INT_FIELD(this, kLengthOffset);
1582
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001583 ASSERT(kShortStringTag + kLongLengthShift == kShortLengthShift);
1584 ASSERT(kMediumStringTag + kLongLengthShift == kMediumLengthShift);
1585 ASSERT(kLongStringTag == 0);
1586
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001587 // Use the map (and not 'this') to compute the size tag, since
1588 // TwoByteStringSize is called during GC when maps are encoded.
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001589 length >>= StringShape(instance_type).size_tag() + kLongLengthShift;
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001590
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001591 return SizeFor(length);
1592}
1593
1594
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001595int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001596 uint32_t length = READ_INT_FIELD(this, kLengthOffset);
1597
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001598 ASSERT(kShortStringTag + kLongLengthShift == kShortLengthShift);
1599 ASSERT(kMediumStringTag + kLongLengthShift == kMediumLengthShift);
1600 ASSERT(kLongStringTag == 0);
1601
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001602 // Use the map (and not 'this') to compute the size tag, since
1603 // AsciiStringSize is called during GC when maps are encoded.
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001604 length >>= StringShape(instance_type).size_tag() + kLongLengthShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001605
1606 return SizeFor(length);
1607}
1608
1609
ager@chromium.org870a0b62008-11-04 11:43:05 +00001610String* ConsString::first() {
1611 return String::cast(READ_FIELD(this, kFirstOffset));
1612}
1613
1614
1615Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001616 return READ_FIELD(this, kFirstOffset);
1617}
1618
1619
ager@chromium.org870a0b62008-11-04 11:43:05 +00001620void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001621 WRITE_FIELD(this, kFirstOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001622 CONDITIONAL_WRITE_BARRIER(this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001623}
1624
1625
ager@chromium.org870a0b62008-11-04 11:43:05 +00001626String* ConsString::second() {
1627 return String::cast(READ_FIELD(this, kSecondOffset));
1628}
1629
1630
1631Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001632 return READ_FIELD(this, kSecondOffset);
1633}
1634
1635
ager@chromium.org870a0b62008-11-04 11:43:05 +00001636void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001637 WRITE_FIELD(this, kSecondOffset, value);
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001638 CONDITIONAL_WRITE_BARRIER(this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001639}
1640
1641
ager@chromium.org870a0b62008-11-04 11:43:05 +00001642String* SlicedString::buffer() {
1643 return String::cast(READ_FIELD(this, kBufferOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001644}
1645
1646
ager@chromium.org870a0b62008-11-04 11:43:05 +00001647void SlicedString::set_buffer(String* buffer) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001648 WRITE_FIELD(this, kBufferOffset, buffer);
1649 WRITE_BARRIER(this, kBufferOffset);
1650}
1651
1652
1653int SlicedString::start() {
1654 return READ_INT_FIELD(this, kStartOffset);
1655}
1656
1657
1658void SlicedString::set_start(int start) {
1659 WRITE_INT_FIELD(this, kStartOffset, start);
1660}
1661
1662
1663ExternalAsciiString::Resource* ExternalAsciiString::resource() {
1664 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1665}
1666
1667
1668void ExternalAsciiString::set_resource(
1669 ExternalAsciiString::Resource* resource) {
1670 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1671}
1672
1673
ager@chromium.org6f10e412009-02-13 10:11:16 +00001674Map* ExternalAsciiString::StringMap(int length) {
1675 Map* map;
1676 // Number of characters: determines the map.
1677 if (length <= String::kMaxShortStringSize) {
1678 map = Heap::short_external_ascii_string_map();
1679 } else if (length <= String::kMaxMediumStringSize) {
1680 map = Heap::medium_external_ascii_string_map();
1681 } else {
1682 map = Heap::long_external_ascii_string_map();
1683 }
1684 return map;
1685}
1686
1687
1688Map* ExternalAsciiString::SymbolMap(int length) {
1689 Map* map;
1690 // Number of characters: determines the map.
1691 if (length <= String::kMaxShortStringSize) {
1692 map = Heap::short_external_ascii_symbol_map();
1693 } else if (length <= String::kMaxMediumStringSize) {
1694 map = Heap::medium_external_ascii_symbol_map();
1695 } else {
1696 map = Heap::long_external_ascii_symbol_map();
1697 }
1698 return map;
1699}
1700
1701
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001702ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
1703 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
1704}
1705
1706
1707void ExternalTwoByteString::set_resource(
1708 ExternalTwoByteString::Resource* resource) {
1709 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
1710}
1711
1712
ager@chromium.org6f10e412009-02-13 10:11:16 +00001713Map* ExternalTwoByteString::StringMap(int length) {
1714 Map* map;
1715 // Number of characters: determines the map.
1716 if (length <= String::kMaxShortStringSize) {
1717 map = Heap::short_external_string_map();
1718 } else if (length <= String::kMaxMediumStringSize) {
1719 map = Heap::medium_external_string_map();
1720 } else {
1721 map = Heap::long_external_string_map();
1722 }
1723 return map;
1724}
1725
1726
1727Map* ExternalTwoByteString::SymbolMap(int length) {
1728 Map* map;
1729 // Number of characters: determines the map.
1730 if (length <= String::kMaxShortStringSize) {
1731 map = Heap::short_external_symbol_map();
1732 } else if (length <= String::kMaxMediumStringSize) {
1733 map = Heap::medium_external_symbol_map();
1734 } else {
1735 map = Heap::long_external_symbol_map();
1736 }
1737 return map;
1738}
1739
1740
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001741byte ByteArray::get(int index) {
1742 ASSERT(index >= 0 && index < this->length());
1743 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
1744}
1745
1746
1747void ByteArray::set(int index, byte value) {
1748 ASSERT(index >= 0 && index < this->length());
1749 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
1750}
1751
1752
1753int ByteArray::get_int(int index) {
1754 ASSERT(index >= 0 && (index * kIntSize) < this->length());
1755 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
1756}
1757
1758
1759ByteArray* ByteArray::FromDataStartAddress(Address address) {
1760 ASSERT_TAG_ALIGNED(address);
1761 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
1762}
1763
1764
1765Address ByteArray::GetDataStartAddress() {
1766 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
1767}
1768
1769
1770int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001771 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
1772}
1773
1774
1775int Map::inobject_properties() {
1776 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001777}
1778
1779
1780int HeapObject::SizeFromMap(Map* map) {
1781 InstanceType instance_type = map->instance_type();
ager@chromium.org5aa501c2009-06-23 07:57:28 +00001782 // Only inline the most frequent cases.
1783 if (instance_type == JS_OBJECT_TYPE ||
1784 (instance_type & (kIsNotStringMask | kStringRepresentationMask)) ==
1785 (kStringTag | kConsStringTag) ||
1786 instance_type == JS_ARRAY_TYPE) return map->instance_size();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001787 if (instance_type == FIXED_ARRAY_TYPE) {
1788 return reinterpret_cast<FixedArray*>(this)->FixedArraySize();
1789 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00001790 if (instance_type == BYTE_ARRAY_TYPE) {
1791 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
1792 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001793 // Otherwise do the general size computation.
1794 return SlowSizeFromMap(map);
1795}
1796
1797
1798void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00001799 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00001800 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001801 ASSERT(0 <= value && value < 256);
1802 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
1803}
1804
1805
ager@chromium.org7c537e22008-10-16 08:43:32 +00001806void Map::set_inobject_properties(int value) {
1807 ASSERT(0 <= value && value < 256);
1808 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
1809}
1810
1811
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001812InstanceType Map::instance_type() {
1813 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
1814}
1815
1816
1817void Map::set_instance_type(InstanceType value) {
1818 ASSERT(0 <= value && value < 256);
1819 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
1820}
1821
1822
1823int Map::unused_property_fields() {
1824 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
1825}
1826
1827
1828void Map::set_unused_property_fields(int value) {
1829 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
1830}
1831
1832
1833byte Map::bit_field() {
1834 return READ_BYTE_FIELD(this, kBitFieldOffset);
1835}
1836
1837
1838void Map::set_bit_field(byte value) {
1839 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
1840}
1841
1842
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00001843byte Map::bit_field2() {
1844 return READ_BYTE_FIELD(this, kBitField2Offset);
1845}
1846
1847
1848void Map::set_bit_field2(byte value) {
1849 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
1850}
1851
1852
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001853void Map::set_non_instance_prototype(bool value) {
1854 if (value) {
1855 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
1856 } else {
1857 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
1858 }
1859}
1860
1861
1862bool Map::has_non_instance_prototype() {
1863 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
1864}
1865
1866
ager@chromium.org870a0b62008-11-04 11:43:05 +00001867void Map::set_is_access_check_needed(bool access_check_needed) {
1868 if (access_check_needed) {
1869 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
1870 } else {
1871 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
1872 }
1873}
1874
1875
1876bool Map::is_access_check_needed() {
1877 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
1878}
1879
1880
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001881Code::Flags Code::flags() {
1882 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
1883}
1884
1885
1886void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001887 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001888 // Make sure that all call stubs have an arguments count.
1889 ASSERT(ExtractKindFromFlags(flags) != CALL_IC ||
1890 ExtractArgumentsCountFromFlags(flags) >= 0);
1891 WRITE_INT_FIELD(this, kFlagsOffset, flags);
1892}
1893
1894
1895Code::Kind Code::kind() {
1896 return ExtractKindFromFlags(flags());
1897}
1898
1899
kasperl@chromium.org71affb52009-05-26 05:44:31 +00001900InLoopFlag Code::ic_in_loop() {
1901 return ExtractICInLoopFromFlags(flags());
1902}
1903
1904
kasper.lund7276f142008-07-30 08:49:36 +00001905InlineCacheState Code::ic_state() {
1906 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001907 // Only allow uninitialized or debugger states for non-IC code
1908 // objects. This is used in the debugger to determine whether or not
1909 // a call to code object has been replaced with a debug break call.
1910 ASSERT(is_inline_cache_stub() ||
1911 result == UNINITIALIZED ||
1912 result == DEBUG_BREAK ||
1913 result == DEBUG_PREPARE_STEP_IN);
1914 return result;
1915}
1916
1917
1918PropertyType Code::type() {
kasper.lund7276f142008-07-30 08:49:36 +00001919 ASSERT(ic_state() == MONOMORPHIC);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001920 return ExtractTypeFromFlags(flags());
1921}
1922
1923
1924int Code::arguments_count() {
1925 ASSERT(is_call_stub() || kind() == STUB);
1926 return ExtractArgumentsCountFromFlags(flags());
1927}
1928
1929
1930CodeStub::Major Code::major_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001931 ASSERT(kind() == STUB);
kasper.lund7276f142008-07-30 08:49:36 +00001932 return static_cast<CodeStub::Major>(READ_BYTE_FIELD(this,
1933 kStubMajorKeyOffset));
1934}
1935
1936
1937void Code::set_major_key(CodeStub::Major major) {
1938 ASSERT(kind() == STUB);
1939 ASSERT(0 <= major && major < 256);
1940 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001941}
1942
1943
1944bool Code::is_inline_cache_stub() {
1945 Kind kind = this->kind();
1946 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
1947}
1948
1949
1950Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00001951 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00001952 InlineCacheState ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001953 PropertyType type,
1954 int argc) {
1955 // Compute the bit mask.
1956 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00001957 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00001958 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001959 bits |= type << kFlagsTypeShift;
1960 bits |= argc << kFlagsArgumentsCountShift;
1961 // Cast to flags and validate result before returning it.
1962 Flags result = static_cast<Flags>(bits);
1963 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00001964 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00001965 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001966 ASSERT(ExtractTypeFromFlags(result) == type);
1967 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
1968 return result;
1969}
1970
1971
1972Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
1973 PropertyType type,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00001974 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001975 int argc) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00001976 return ComputeFlags(kind, in_loop, MONOMORPHIC, type, argc);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001977}
1978
1979
1980Code::Kind Code::ExtractKindFromFlags(Flags flags) {
1981 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
1982 return static_cast<Kind>(bits);
1983}
1984
1985
kasper.lund7276f142008-07-30 08:49:36 +00001986InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
1987 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001988 return static_cast<InlineCacheState>(bits);
1989}
1990
1991
kasperl@chromium.org71affb52009-05-26 05:44:31 +00001992InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
1993 int bits = (flags & kFlagsICInLoopMask);
1994 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
1995}
1996
1997
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001998PropertyType Code::ExtractTypeFromFlags(Flags flags) {
1999 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
2000 return static_cast<PropertyType>(bits);
2001}
2002
2003
2004int Code::ExtractArgumentsCountFromFlags(Flags flags) {
2005 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
2006}
2007
2008
2009Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
2010 int bits = flags & ~kFlagsTypeMask;
2011 return static_cast<Flags>(bits);
2012}
2013
2014
ager@chromium.org8bb60582008-12-11 12:02:20 +00002015Code* Code::GetCodeFromTargetAddress(Address address) {
2016 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
2017 // GetCodeFromTargetAddress might be called when marking objects during mark
2018 // sweep. reinterpret_cast is therefore used instead of the more appropriate
2019 // Code::cast. Code::cast does not work when the object's map is
2020 // marked.
2021 Code* result = reinterpret_cast<Code*>(code);
2022 return result;
2023}
2024
2025
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002026Object* Map::prototype() {
2027 return READ_FIELD(this, kPrototypeOffset);
2028}
2029
2030
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002031void Map::set_prototype(Object* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002032 ASSERT(value->IsNull() || value->IsJSObject());
2033 WRITE_FIELD(this, kPrototypeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002034 CONDITIONAL_WRITE_BARRIER(this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002035}
2036
2037
2038ACCESSORS(Map, instance_descriptors, DescriptorArray,
2039 kInstanceDescriptorsOffset)
2040ACCESSORS(Map, code_cache, FixedArray, kCodeCacheOffset)
2041ACCESSORS(Map, constructor, Object, kConstructorOffset)
2042
2043ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
2044ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
2045
2046ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
2047ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002048ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002049
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002050ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002051
2052ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
2053ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
2054ACCESSORS(AccessorInfo, data, Object, kDataOffset)
2055ACCESSORS(AccessorInfo, name, Object, kNameOffset)
2056ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
2057
2058ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
2059ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
2060ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
2061
2062ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
2063ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
2064ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
2065ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
2066ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
2067ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
2068
2069ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
2070ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
2071
2072ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
2073ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
2074
2075ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
2076ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002077ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
2078 kPropertyAccessorsOffset)
2079ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
2080 kPrototypeTemplateOffset)
2081ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
2082ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
2083 kNamedPropertyHandlerOffset)
2084ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
2085 kIndexedPropertyHandlerOffset)
2086ACCESSORS(FunctionTemplateInfo, instance_template, Object,
2087 kInstanceTemplateOffset)
2088ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
2089ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002090ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
2091 kInstanceCallHandlerOffset)
2092ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
2093 kAccessCheckInfoOffset)
2094ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
2095
2096ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00002097ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
2098 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002099
2100ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
2101ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
2102
2103ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
2104
2105ACCESSORS(Script, source, Object, kSourceOffset)
2106ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002107ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002108ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
2109ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002110ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00002111ACCESSORS(Script, context_data, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002112ACCESSORS(Script, wrapper, Proxy, kWrapperOffset)
2113ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002114ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
iposva@chromium.org245aa852009-02-10 00:49:54 +00002115ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00002116ACCESSORS(Script, eval_from_function, Object, kEvalFromFunctionOffset)
2117ACCESSORS(Script, eval_from_instructions_offset, Smi,
2118 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002119
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002120#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002121ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
2122ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
2123ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
2124ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
2125
2126ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
2127ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
2128ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
2129ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00002130#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002131
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002132ACCESSORS(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002133ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
2134ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
2135 kInstanceClassNameOffset)
2136ACCESSORS(SharedFunctionInfo, function_data, Object,
2137 kExternalReferenceDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002138ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
2139ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00002140ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002141
2142BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
2143 kHiddenPrototypeBit)
2144BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
2145BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
2146 kNeedsAccessCheckBit)
2147BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
2148 kIsExpressionBit)
2149BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
2150 kIsTopLevelBit)
2151
2152INT_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
2153INT_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
2154 kFormalParameterCountOffset)
2155INT_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
2156 kExpectedNofPropertiesOffset)
2157INT_ACCESSORS(SharedFunctionInfo, start_position_and_type,
2158 kStartPositionAndTypeOffset)
2159INT_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
2160INT_ACCESSORS(SharedFunctionInfo, function_token_position,
2161 kFunctionTokenPositionOffset)
2162
2163
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002164void SharedFunctionInfo::DontAdaptArguments() {
2165 ASSERT(code()->kind() == Code::BUILTIN);
2166 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
2167}
2168
2169
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002170int SharedFunctionInfo::start_position() {
2171 return start_position_and_type() >> kStartPositionShift;
2172}
2173
2174
2175void SharedFunctionInfo::set_start_position(int start_position) {
2176 set_start_position_and_type((start_position << kStartPositionShift)
2177 | (start_position_and_type() & ~kStartPositionMask));
2178}
2179
2180
2181Code* SharedFunctionInfo::code() {
2182 return Code::cast(READ_FIELD(this, kCodeOffset));
2183}
2184
2185
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002186void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002187 WRITE_FIELD(this, kCodeOffset, value);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002188 CONDITIONAL_WRITE_BARRIER(this, kCodeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002189}
2190
2191
2192bool SharedFunctionInfo::is_compiled() {
2193 // TODO(1242782): Create a code kind for uncompiled code.
2194 return code()->kind() != Code::STUB;
2195}
2196
2197
2198bool JSFunction::IsBoilerplate() {
2199 return map() == Heap::boilerplate_function_map();
2200}
2201
2202
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002203bool JSObject::IsLoaded() {
2204 return !map()->needs_loading();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002205}
2206
2207
2208Code* JSFunction::code() {
2209 return shared()->code();
2210}
2211
2212
2213void JSFunction::set_code(Code* value) {
2214 shared()->set_code(value);
2215}
2216
2217
2218Context* JSFunction::context() {
2219 return Context::cast(READ_FIELD(this, kContextOffset));
2220}
2221
2222
2223Object* JSFunction::unchecked_context() {
2224 return READ_FIELD(this, kContextOffset);
2225}
2226
2227
2228void JSFunction::set_context(Object* value) {
2229 ASSERT(value == Heap::undefined_value() || value->IsContext());
2230 WRITE_FIELD(this, kContextOffset, value);
2231 WRITE_BARRIER(this, kContextOffset);
2232}
2233
2234ACCESSORS(JSFunction, prototype_or_initial_map, Object,
2235 kPrototypeOrInitialMapOffset)
2236
2237
2238Map* JSFunction::initial_map() {
2239 return Map::cast(prototype_or_initial_map());
2240}
2241
2242
2243void JSFunction::set_initial_map(Map* value) {
2244 set_prototype_or_initial_map(value);
2245}
2246
2247
2248bool JSFunction::has_initial_map() {
2249 return prototype_or_initial_map()->IsMap();
2250}
2251
2252
2253bool JSFunction::has_instance_prototype() {
2254 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
2255}
2256
2257
2258bool JSFunction::has_prototype() {
2259 return map()->has_non_instance_prototype() || has_instance_prototype();
2260}
2261
2262
2263Object* JSFunction::instance_prototype() {
2264 ASSERT(has_instance_prototype());
2265 if (has_initial_map()) return initial_map()->prototype();
2266 // When there is no initial map and the prototype is a JSObject, the
2267 // initial map field is used for the prototype field.
2268 return prototype_or_initial_map();
2269}
2270
2271
2272Object* JSFunction::prototype() {
2273 ASSERT(has_prototype());
2274 // If the function's prototype property has been set to a non-JSObject
2275 // value, that value is stored in the constructor field of the map.
2276 if (map()->has_non_instance_prototype()) return map()->constructor();
2277 return instance_prototype();
2278}
2279
2280
2281bool JSFunction::is_compiled() {
2282 return shared()->is_compiled();
2283}
2284
2285
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002286int JSFunction::NumberOfLiterals() {
2287 return literals()->length();
2288}
2289
2290
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002291Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
2292 ASSERT(0 <= id && id < kJSBuiltinsCount);
2293 return READ_FIELD(this, kJSBuiltinsOffset + (id * kPointerSize));
2294}
2295
2296
2297void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
2298 Object* value) {
2299 ASSERT(0 <= id && id < kJSBuiltinsCount);
2300 WRITE_FIELD(this, kJSBuiltinsOffset + (id * kPointerSize), value);
2301 WRITE_BARRIER(this, kJSBuiltinsOffset + (id * kPointerSize));
2302}
2303
2304
2305Address Proxy::proxy() {
2306 return AddressFrom<Address>(READ_INT_FIELD(this, kProxyOffset));
2307}
2308
2309
2310void Proxy::set_proxy(Address value) {
2311 WRITE_INT_FIELD(this, kProxyOffset, OffsetFrom(value));
2312}
2313
2314
2315void Proxy::ProxyIterateBody(ObjectVisitor* visitor) {
2316 visitor->VisitExternalReference(
2317 reinterpret_cast<Address *>(FIELD_ADDR(this, kProxyOffset)));
2318}
2319
2320
2321ACCESSORS(JSValue, value, Object, kValueOffset)
2322
2323
2324JSValue* JSValue::cast(Object* obj) {
2325 ASSERT(obj->IsJSValue());
2326 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
2327 return reinterpret_cast<JSValue*>(obj);
2328}
2329
2330
2331INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
2332INT_ACCESSORS(Code, relocation_size, kRelocationSizeOffset)
2333INT_ACCESSORS(Code, sinfo_size, kSInfoSizeOffset)
2334
2335
2336Code::ICTargetState Code::ic_flag() {
kasper.lund7276f142008-07-30 08:49:36 +00002337 return static_cast<ICTargetState>(READ_BYTE_FIELD(this, kICFlagOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002338}
2339
2340
2341void Code::set_ic_flag(ICTargetState value) {
kasper.lund7276f142008-07-30 08:49:36 +00002342 WRITE_BYTE_FIELD(this, kICFlagOffset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002343}
2344
2345
2346byte* Code::instruction_start() {
2347 return FIELD_ADDR(this, kHeaderSize);
2348}
2349
2350
2351int Code::body_size() {
2352 return RoundUp(instruction_size() + relocation_size(), kObjectAlignment);
2353}
2354
2355
2356byte* Code::relocation_start() {
kasperl@chromium.org061ef742009-02-27 12:16:20 +00002357 return FIELD_ADDR(this, kHeaderSize + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002358}
2359
2360
2361byte* Code::entry() {
2362 return instruction_start();
2363}
2364
2365
2366bool Code::contains(byte* pc) {
2367 return (instruction_start() <= pc) &&
2368 (pc < instruction_start() + instruction_size());
2369}
2370
2371
2372byte* Code::sinfo_start() {
kasperl@chromium.org061ef742009-02-27 12:16:20 +00002373 return FIELD_ADDR(this, kHeaderSize + body_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002374}
2375
2376
2377ACCESSORS(JSArray, length, Object, kLengthOffset)
2378
2379
ager@chromium.org236ad962008-09-25 09:45:57 +00002380ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00002381
2382
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002383JSRegExp::Type JSRegExp::TypeTag() {
2384 Object* data = this->data();
2385 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
2386 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
2387 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00002388}
2389
2390
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002391int JSRegExp::CaptureCount() {
2392 switch (TypeTag()) {
2393 case ATOM:
2394 return 0;
2395 case IRREGEXP:
2396 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
2397 default:
2398 UNREACHABLE();
2399 return -1;
2400 }
2401}
2402
2403
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002404JSRegExp::Flags JSRegExp::GetFlags() {
2405 ASSERT(this->data()->IsFixedArray());
2406 Object* data = this->data();
2407 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
2408 return Flags(smi->value());
2409}
2410
2411
2412String* JSRegExp::Pattern() {
2413 ASSERT(this->data()->IsFixedArray());
2414 Object* data = this->data();
2415 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
2416 return pattern;
2417}
2418
2419
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002420Object* JSRegExp::DataAt(int index) {
2421 ASSERT(TypeTag() != NOT_COMPILED);
2422 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00002423}
2424
2425
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00002426void JSRegExp::SetDataAt(int index, Object* value) {
2427 ASSERT(TypeTag() != NOT_COMPILED);
2428 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
2429 FixedArray::cast(data())->set(index, value);
2430}
2431
2432
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002433bool JSObject::HasFastElements() {
2434 return !elements()->IsDictionary();
2435}
2436
2437
2438bool JSObject::HasNamedInterceptor() {
2439 return map()->has_named_interceptor();
2440}
2441
2442
2443bool JSObject::HasIndexedInterceptor() {
2444 return map()->has_indexed_interceptor();
2445}
2446
2447
2448Dictionary* JSObject::property_dictionary() {
2449 ASSERT(!HasFastProperties());
2450 return Dictionary::cast(properties());
2451}
2452
2453
2454Dictionary* JSObject::element_dictionary() {
2455 ASSERT(!HasFastElements());
2456 return Dictionary::cast(elements());
2457}
2458
2459
2460bool String::HasHashCode() {
2461 return (length_field() & kHashComputedMask) != 0;
2462}
2463
2464
2465uint32_t String::Hash() {
2466 // Fast case: has hash code already been computed?
ager@chromium.org7c537e22008-10-16 08:43:32 +00002467 uint32_t field = length_field();
2468 if (field & kHashComputedMask) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002469 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002470 return ComputeAndSetHash();
2471}
2472
2473
ager@chromium.org7c537e22008-10-16 08:43:32 +00002474StringHasher::StringHasher(int length)
2475 : length_(length),
2476 raw_running_hash_(0),
2477 array_index_(0),
2478 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
2479 is_first_char_(true),
2480 is_valid_(true) { }
2481
2482
2483bool StringHasher::has_trivial_hash() {
2484 return length_ > String::kMaxMediumStringSize;
2485}
2486
2487
2488void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002489 // Use the Jenkins one-at-a-time hash function to update the hash
2490 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002491 raw_running_hash_ += c;
2492 raw_running_hash_ += (raw_running_hash_ << 10);
2493 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002494 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002495 if (is_array_index_) {
2496 if (c < '0' || c > '9') {
2497 is_array_index_ = false;
2498 } else {
2499 int d = c - '0';
2500 if (is_first_char_) {
2501 is_first_char_ = false;
2502 if (c == '0' && length_ > 1) {
2503 is_array_index_ = false;
2504 return;
2505 }
2506 }
2507 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
2508 is_array_index_ = false;
2509 } else {
2510 array_index_ = array_index_ * 10 + d;
2511 }
2512 }
2513 }
2514}
2515
2516
2517void StringHasher::AddCharacterNoIndex(uc32 c) {
2518 ASSERT(!is_array_index());
2519 raw_running_hash_ += c;
2520 raw_running_hash_ += (raw_running_hash_ << 10);
2521 raw_running_hash_ ^= (raw_running_hash_ >> 6);
2522}
2523
2524
2525uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00002526 // Get the calculated raw hash value and do some more bit ops to distribute
2527 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00002528 uint32_t result = raw_running_hash_;
2529 result += (result << 3);
2530 result ^= (result >> 11);
2531 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00002532 if (result == 0) {
2533 result = 27;
2534 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00002535 return result;
2536}
2537
2538
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002539bool String::AsArrayIndex(uint32_t* index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002540 uint32_t field = length_field();
2541 if ((field & kHashComputedMask) && !(field & kIsArrayIndexMask)) return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002542 return SlowAsArrayIndex(index);
2543}
2544
2545
2546Object* JSObject::GetPrototype() {
2547 return JSObject::cast(this)->map()->prototype();
2548}
2549
2550
2551PropertyAttributes JSObject::GetPropertyAttribute(String* key) {
2552 return GetPropertyAttributeWithReceiver(this, key);
2553}
2554
2555
2556bool JSObject::HasElement(uint32_t index) {
2557 return HasElementWithReceiver(this, index);
2558}
2559
2560
ager@chromium.orge2902be2009-06-08 12:21:35 +00002561Smi* JSObject::InterceptorPropertyLookupHint(String* name) {
2562 // TODO(antonm): Do we want to do any shortcuts for global object?
2563 if (HasFastProperties()) {
2564 LookupResult lookup;
2565 LocalLookupRealNamedProperty(name, &lookup);
2566 if (lookup.IsValid()) {
2567 if (lookup.type() == FIELD && lookup.IsCacheable()) {
2568 return Smi::FromInt(lookup.GetFieldIndex());
2569 }
2570 } else {
2571 return Smi::FromInt(kLookupInPrototype);
2572 }
2573 }
2574
2575 return Smi::FromInt(kLookupInHolder);
2576}
2577
2578
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002579bool AccessorInfo::all_can_read() {
2580 return BooleanBit::get(flag(), kAllCanReadBit);
2581}
2582
2583
2584void AccessorInfo::set_all_can_read(bool value) {
2585 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
2586}
2587
2588
2589bool AccessorInfo::all_can_write() {
2590 return BooleanBit::get(flag(), kAllCanWriteBit);
2591}
2592
2593
2594void AccessorInfo::set_all_can_write(bool value) {
2595 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
2596}
2597
2598
ager@chromium.org870a0b62008-11-04 11:43:05 +00002599bool AccessorInfo::prohibits_overwriting() {
2600 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
2601}
2602
2603
2604void AccessorInfo::set_prohibits_overwriting(bool value) {
2605 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
2606}
2607
2608
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002609PropertyAttributes AccessorInfo::property_attributes() {
2610 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
2611}
2612
2613
2614void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
2615 ASSERT(AttributesField::is_valid(attributes));
2616 int rest_value = flag()->value() & ~AttributesField::mask();
2617 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
2618}
2619
2620void Dictionary::SetEntry(int entry,
2621 Object* key,
2622 Object* value,
2623 PropertyDetails details) {
2624 ASSERT(!key->IsString() || details.index() > 0);
2625 int index = EntryToIndex(entry);
2626 WriteBarrierMode mode = GetWriteBarrierMode();
2627 set(index, key, mode);
2628 set(index+1, value, mode);
2629 fast_set(this, index+2, details.AsSmi());
2630}
2631
2632
2633void Map::ClearCodeCache() {
2634 // No write barrier is needed since empty_fixed_array is not in new space.
2635 // Please note this function is used during marking:
2636 // - MarkCompactCollector::MarkUnmarkedObject
2637 ASSERT(!Heap::InNewSpace(Heap::empty_fixed_array()));
2638 WRITE_FIELD(this, kCodeCacheOffset, Heap::empty_fixed_array());
2639}
2640
2641
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002642void JSArray::EnsureSize(int required_size) {
2643 ASSERT(HasFastElements());
2644 if (elements()->length() >= required_size) return;
2645 Expand(required_size);
2646}
2647
2648
ager@chromium.org7c537e22008-10-16 08:43:32 +00002649void JSArray::SetContent(FixedArray* storage) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00002650 set_length(Smi::FromInt(storage->length()), SKIP_WRITE_BARRIER);
ager@chromium.org7c537e22008-10-16 08:43:32 +00002651 set_elements(storage);
2652}
2653
2654
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002655Object* FixedArray::Copy() {
2656 if (length() == 0) return this;
2657 return Heap::CopyFixedArray(this);
2658}
2659
2660
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002661#undef CAST_ACCESSOR
2662#undef INT_ACCESSORS
2663#undef SMI_ACCESSORS
2664#undef ACCESSORS
2665#undef FIELD_ADDR
2666#undef READ_FIELD
2667#undef WRITE_FIELD
2668#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002669#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002670#undef READ_MEMADDR_FIELD
2671#undef WRITE_MEMADDR_FIELD
2672#undef READ_DOUBLE_FIELD
2673#undef WRITE_DOUBLE_FIELD
2674#undef READ_INT_FIELD
2675#undef WRITE_INT_FIELD
2676#undef READ_SHORT_FIELD
2677#undef WRITE_SHORT_FIELD
2678#undef READ_BYTE_FIELD
2679#undef WRITE_BYTE_FIELD
2680
2681
2682} } // namespace v8::internal
2683
2684#endif // V8_OBJECTS_INL_H_