blob: 2417c3207b3e11279bc0640f5cf97df379993754 [file] [log] [blame]
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00001// Copyright 2011 the V8 project authors. All rights reserved.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002// Redistribution and use in source and binary forms, with or without
3// modification, are permitted provided that the following conditions are
4// met:
5//
6// * Redistributions of source code must retain the above copyright
7// notice, this list of conditions and the following disclaimer.
8// * Redistributions in binary form must reproduce the above
9// copyright notice, this list of conditions and the following
10// disclaimer in the documentation and/or other materials provided
11// with the distribution.
12// * Neither the name of Google Inc. nor the names of its
13// contributors may be used to endorse or promote products derived
14// from this software without specific prior written permission.
15//
16// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
17// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
20// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27//
28// Review notes:
29//
ager@chromium.org32912102009-01-16 10:38:43 +000030// - The use of macros in these inline functions may seem superfluous
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000031// but it is absolutely needed to make sure gcc generates optimal
32// code. gcc is not happy when attempting to inline too deep.
33//
34
35#ifndef V8_OBJECTS_INL_H_
36#define V8_OBJECTS_INL_H_
37
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000038#include "objects.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000039#include "contexts.h"
40#include "conversions-inl.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000041#include "heap.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000042#include "isolate.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000043#include "property.h"
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +000044#include "spaces.h"
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000045#include "v8memory.h"
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000046
kasperl@chromium.org71affb52009-05-26 05:44:31 +000047namespace v8 {
48namespace internal {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000049
50PropertyDetails::PropertyDetails(Smi* smi) {
51 value_ = smi->value();
52}
53
54
55Smi* PropertyDetails::AsSmi() {
56 return Smi::FromInt(value_);
57}
58
59
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000060PropertyDetails PropertyDetails::AsDeleted() {
ager@chromium.org378b34e2011-01-28 08:04:38 +000061 Smi* smi = Smi::FromInt(value_ | DeletedField::encode(1));
kasperl@chromium.org2abc4502009-07-02 07:00:29 +000062 return PropertyDetails(smi);
63}
64
65
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000066#define CAST_ACCESSOR(type) \
67 type* type::cast(Object* object) { \
68 ASSERT(object->Is##type()); \
69 return reinterpret_cast<type*>(object); \
70 }
71
72
73#define INT_ACCESSORS(holder, name, offset) \
74 int holder::name() { return READ_INT_FIELD(this, offset); } \
75 void holder::set_##name(int value) { WRITE_INT_FIELD(this, offset, value); }
76
77
78#define ACCESSORS(holder, name, type, offset) \
79 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +000080 void holder::set_##name(type* value, WriteBarrierMode mode) { \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000081 WRITE_FIELD(this, offset, value); \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +000082 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode); \
83 }
84
85
86// GC-safe accessors do not use HeapObject::GetHeap(), but access TLS instead.
87#define ACCESSORS_GCSAFE(holder, name, type, offset) \
88 type* holder::name() { return type::cast(READ_FIELD(this, offset)); } \
89 void holder::set_##name(type* value, WriteBarrierMode mode) { \
90 WRITE_FIELD(this, offset, value); \
91 CONDITIONAL_WRITE_BARRIER(HEAP, this, offset, mode); \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +000092 }
93
94
95#define SMI_ACCESSORS(holder, name, offset) \
96 int holder::name() { \
97 Object* value = READ_FIELD(this, offset); \
98 return Smi::cast(value)->value(); \
99 } \
100 void holder::set_##name(int value) { \
101 WRITE_FIELD(this, offset, Smi::FromInt(value)); \
102 }
103
104
sgjesse@chromium.org911335c2009-08-19 12:59:44 +0000105#define BOOL_GETTER(holder, field, name, offset) \
106 bool holder::name() { \
107 return BooleanBit::get(field(), offset); \
108 } \
109
110
111#define BOOL_ACCESSORS(holder, field, name, offset) \
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000112 bool holder::name() { \
113 return BooleanBit::get(field(), offset); \
114 } \
115 void holder::set_##name(bool value) { \
116 set_##field(BooleanBit::set(field(), offset, value)); \
117 }
118
119
sgjesse@chromium.org900d3b72009-08-07 11:24:25 +0000120bool Object::IsInstanceOf(FunctionTemplateInfo* expected) {
121 // There is a constraint on the object; check.
122 if (!this->IsJSObject()) return false;
123 // Fetch the constructor function of the object.
124 Object* cons_obj = JSObject::cast(this)->map()->constructor();
125 if (!cons_obj->IsJSFunction()) return false;
126 JSFunction* fun = JSFunction::cast(cons_obj);
127 // Iterate through the chain of inheriting function templates to
128 // see if the required one occurs.
129 for (Object* type = fun->shared()->function_data();
130 type->IsFunctionTemplateInfo();
131 type = FunctionTemplateInfo::cast(type)->parent_template()) {
132 if (type == expected) return true;
133 }
134 // Didn't find the required type in the inheritance chain.
135 return false;
136}
137
138
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000139bool Object::IsSmi() {
140 return HAS_SMI_TAG(this);
141}
142
143
144bool Object::IsHeapObject() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000145 return Internals::HasHeapObjectTag(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000146}
147
148
149bool Object::IsHeapNumber() {
150 return Object::IsHeapObject()
151 && HeapObject::cast(this)->map()->instance_type() == HEAP_NUMBER_TYPE;
152}
153
154
155bool Object::IsString() {
156 return Object::IsHeapObject()
157 && HeapObject::cast(this)->map()->instance_type() < FIRST_NONSTRING_TYPE;
158}
159
160
ricow@chromium.org9fa09672011-07-25 11:05:35 +0000161bool Object::IsSpecObject() {
162 return Object::IsHeapObject()
163 && HeapObject::cast(this)->map()->instance_type() >= FIRST_SPEC_OBJECT_TYPE;
164}
165
166
ager@chromium.org870a0b62008-11-04 11:43:05 +0000167bool Object::IsSymbol() {
168 if (!this->IsHeapObject()) return false;
169 uint32_t type = HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000170 // Because the symbol tag is non-zero and no non-string types have the
171 // symbol bit set we can test for symbols with a very simple test
172 // operation.
173 ASSERT(kSymbolTag != 0);
174 ASSERT(kNotStringTag + kIsSymbolMask > LAST_TYPE);
175 return (type & kIsSymbolMask) != 0;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000176}
177
178
179bool Object::IsConsString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000180 if (!this->IsHeapObject()) return false;
181 uint32_t type = HeapObject::cast(this)->map()->instance_type();
182 return (type & (kIsNotStringMask | kStringRepresentationMask)) ==
183 (kStringTag | kConsStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000184}
185
186
ager@chromium.org870a0b62008-11-04 11:43:05 +0000187bool Object::IsSeqString() {
188 if (!IsString()) return false;
189 return StringShape(String::cast(this)).IsSequential();
190}
191
192
193bool Object::IsSeqAsciiString() {
194 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000195 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000196 String::cast(this)->IsAsciiRepresentation();
ager@chromium.org870a0b62008-11-04 11:43:05 +0000197}
198
199
200bool Object::IsSeqTwoByteString() {
201 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000202 return StringShape(String::cast(this)).IsSequential() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000203 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000204}
205
206
207bool Object::IsExternalString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000208 if (!IsString()) return false;
209 return StringShape(String::cast(this)).IsExternal();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000210}
211
212
213bool Object::IsExternalAsciiString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000214 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000215 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000216 String::cast(this)->IsAsciiRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000217}
218
219
220bool Object::IsExternalTwoByteString() {
ager@chromium.org870a0b62008-11-04 11:43:05 +0000221 if (!IsString()) return false;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +0000222 return StringShape(String::cast(this)).IsExternal() &&
ager@chromium.org5ec48922009-05-05 07:25:34 +0000223 String::cast(this)->IsTwoByteRepresentation();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000224}
225
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000226bool Object::HasValidElements() {
227 // Dictionary is covered under FixedArray.
228 return IsFixedArray() || IsFixedDoubleArray() || IsExternalArray();
229}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000230
ager@chromium.org870a0b62008-11-04 11:43:05 +0000231StringShape::StringShape(String* str)
232 : type_(str->map()->instance_type()) {
233 set_valid();
234 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000235}
236
237
ager@chromium.org870a0b62008-11-04 11:43:05 +0000238StringShape::StringShape(Map* map)
239 : type_(map->instance_type()) {
240 set_valid();
241 ASSERT((type_ & kIsNotStringMask) == kStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000242}
243
244
ager@chromium.org870a0b62008-11-04 11:43:05 +0000245StringShape::StringShape(InstanceType t)
246 : type_(static_cast<uint32_t>(t)) {
247 set_valid();
248 ASSERT((type_ & kIsNotStringMask) == kStringTag);
249}
250
251
252bool StringShape::IsSymbol() {
253 ASSERT(valid());
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000254 ASSERT(kSymbolTag != 0);
255 return (type_ & kIsSymbolMask) != 0;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000256}
257
258
ager@chromium.org5ec48922009-05-05 07:25:34 +0000259bool String::IsAsciiRepresentation() {
260 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000261 return (type & kStringEncodingMask) == kAsciiStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000262}
263
264
ager@chromium.org5ec48922009-05-05 07:25:34 +0000265bool String::IsTwoByteRepresentation() {
266 uint32_t type = map()->instance_type();
ager@chromium.org5ec48922009-05-05 07:25:34 +0000267 return (type & kStringEncodingMask) == kTwoByteStringTag;
ager@chromium.org870a0b62008-11-04 11:43:05 +0000268}
269
270
ricow@chromium.org5ad5ace2010-06-23 09:06:43 +0000271bool String::HasOnlyAsciiChars() {
272 uint32_t type = map()->instance_type();
273 return (type & kStringEncodingMask) == kAsciiStringTag ||
274 (type & kAsciiDataHintMask) == kAsciiDataHintTag;
ricow@chromium.orgaa1b6162010-03-29 07:44:58 +0000275}
276
277
ager@chromium.org870a0b62008-11-04 11:43:05 +0000278bool StringShape::IsCons() {
279 return (type_ & kStringRepresentationMask) == kConsStringTag;
280}
281
282
ager@chromium.org870a0b62008-11-04 11:43:05 +0000283bool StringShape::IsExternal() {
284 return (type_ & kStringRepresentationMask) == kExternalStringTag;
285}
286
287
288bool StringShape::IsSequential() {
289 return (type_ & kStringRepresentationMask) == kSeqStringTag;
290}
291
292
293StringRepresentationTag StringShape::representation_tag() {
294 uint32_t tag = (type_ & kStringRepresentationMask);
295 return static_cast<StringRepresentationTag>(tag);
296}
297
298
299uint32_t StringShape::full_representation_tag() {
300 return (type_ & (kStringRepresentationMask | kStringEncodingMask));
301}
302
303
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000304STATIC_CHECK((kStringRepresentationMask | kStringEncodingMask) ==
305 Internals::kFullStringRepresentationMask);
306
307
ager@chromium.org870a0b62008-11-04 11:43:05 +0000308bool StringShape::IsSequentialAscii() {
309 return full_representation_tag() == (kSeqStringTag | kAsciiStringTag);
310}
311
312
313bool StringShape::IsSequentialTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000314 return full_representation_tag() == (kSeqStringTag | kTwoByteStringTag);
ager@chromium.org870a0b62008-11-04 11:43:05 +0000315}
316
317
318bool StringShape::IsExternalAscii() {
319 return full_representation_tag() == (kExternalStringTag | kAsciiStringTag);
320}
321
322
323bool StringShape::IsExternalTwoByte() {
ager@chromium.org80787b72009-04-17 10:24:24 +0000324 return full_representation_tag() == (kExternalStringTag | kTwoByteStringTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000325}
326
327
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000328STATIC_CHECK((kExternalStringTag | kTwoByteStringTag) ==
329 Internals::kExternalTwoByteRepresentationTag);
330
331
ager@chromium.orga74f0da2008-12-03 16:05:52 +0000332uc32 FlatStringReader::Get(int index) {
333 ASSERT(0 <= index && index <= length_);
334 if (is_ascii_) {
335 return static_cast<const byte*>(start_)[index];
336 } else {
337 return static_cast<const uc16*>(start_)[index];
338 }
339}
340
341
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000342bool Object::IsNumber() {
343 return IsSmi() || IsHeapNumber();
344}
345
346
347bool Object::IsByteArray() {
348 return Object::IsHeapObject()
349 && HeapObject::cast(this)->map()->instance_type() == BYTE_ARRAY_TYPE;
350}
351
352
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000353bool Object::IsExternalPixelArray() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000354 return Object::IsHeapObject() &&
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +0000355 HeapObject::cast(this)->map()->instance_type() ==
356 EXTERNAL_PIXEL_ARRAY_TYPE;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +0000357}
358
359
ager@chromium.org3811b432009-10-28 14:53:37 +0000360bool Object::IsExternalArray() {
361 if (!Object::IsHeapObject())
362 return false;
363 InstanceType instance_type =
364 HeapObject::cast(this)->map()->instance_type();
fschneider@chromium.org0c20e672010-01-14 15:28:53 +0000365 return (instance_type >= FIRST_EXTERNAL_ARRAY_TYPE &&
366 instance_type <= LAST_EXTERNAL_ARRAY_TYPE);
ager@chromium.org3811b432009-10-28 14:53:37 +0000367}
368
369
370bool Object::IsExternalByteArray() {
371 return Object::IsHeapObject() &&
372 HeapObject::cast(this)->map()->instance_type() ==
373 EXTERNAL_BYTE_ARRAY_TYPE;
374}
375
376
377bool Object::IsExternalUnsignedByteArray() {
378 return Object::IsHeapObject() &&
379 HeapObject::cast(this)->map()->instance_type() ==
380 EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE;
381}
382
383
384bool Object::IsExternalShortArray() {
385 return Object::IsHeapObject() &&
386 HeapObject::cast(this)->map()->instance_type() ==
387 EXTERNAL_SHORT_ARRAY_TYPE;
388}
389
390
391bool Object::IsExternalUnsignedShortArray() {
392 return Object::IsHeapObject() &&
393 HeapObject::cast(this)->map()->instance_type() ==
394 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE;
395}
396
397
398bool Object::IsExternalIntArray() {
399 return Object::IsHeapObject() &&
400 HeapObject::cast(this)->map()->instance_type() ==
401 EXTERNAL_INT_ARRAY_TYPE;
402}
403
404
405bool Object::IsExternalUnsignedIntArray() {
406 return Object::IsHeapObject() &&
407 HeapObject::cast(this)->map()->instance_type() ==
408 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE;
409}
410
411
412bool Object::IsExternalFloatArray() {
413 return Object::IsHeapObject() &&
414 HeapObject::cast(this)->map()->instance_type() ==
415 EXTERNAL_FLOAT_ARRAY_TYPE;
416}
417
418
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +0000419bool Object::IsExternalDoubleArray() {
420 return Object::IsHeapObject() &&
421 HeapObject::cast(this)->map()->instance_type() ==
422 EXTERNAL_DOUBLE_ARRAY_TYPE;
423}
424
425
lrn@chromium.org303ada72010-10-27 09:33:13 +0000426bool MaybeObject::IsFailure() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000427 return HAS_FAILURE_TAG(this);
428}
429
430
lrn@chromium.org303ada72010-10-27 09:33:13 +0000431bool MaybeObject::IsRetryAfterGC() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000432 return HAS_FAILURE_TAG(this)
433 && Failure::cast(this)->type() == Failure::RETRY_AFTER_GC;
434}
435
436
lrn@chromium.org303ada72010-10-27 09:33:13 +0000437bool MaybeObject::IsOutOfMemory() {
ager@chromium.org7c537e22008-10-16 08:43:32 +0000438 return HAS_FAILURE_TAG(this)
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000439 && Failure::cast(this)->IsOutOfMemoryException();
ager@chromium.org7c537e22008-10-16 08:43:32 +0000440}
441
442
lrn@chromium.org303ada72010-10-27 09:33:13 +0000443bool MaybeObject::IsException() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000444 return this == Failure::Exception();
445}
446
447
lrn@chromium.org303ada72010-10-27 09:33:13 +0000448bool MaybeObject::IsTheHole() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000449 return !IsFailure() && ToObjectUnchecked()->IsTheHole();
lrn@chromium.org303ada72010-10-27 09:33:13 +0000450}
451
452
453Failure* Failure::cast(MaybeObject* obj) {
454 ASSERT(HAS_FAILURE_TAG(obj));
455 return reinterpret_cast<Failure*>(obj);
456}
457
458
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000459bool Object::IsJSReceiver() {
460 return IsHeapObject() &&
461 HeapObject::cast(this)->map()->instance_type() >= FIRST_JS_RECEIVER_TYPE;
462}
463
464
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000465bool Object::IsJSObject() {
ricow@chromium.orgd2be9012011-06-01 06:00:58 +0000466 return IsJSReceiver() && !IsJSProxy();
467}
468
469
470bool Object::IsJSProxy() {
471 return Object::IsHeapObject() &&
472 (HeapObject::cast(this)->map()->instance_type() == JS_PROXY_TYPE ||
473 HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_PROXY_TYPE);
474}
475
476
477bool Object::IsJSFunctionProxy() {
478 return Object::IsHeapObject() &&
479 HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_PROXY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000480}
481
482
ager@chromium.org32912102009-01-16 10:38:43 +0000483bool Object::IsJSContextExtensionObject() {
484 return IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000485 && (HeapObject::cast(this)->map()->instance_type() ==
486 JS_CONTEXT_EXTENSION_OBJECT_TYPE);
ager@chromium.org32912102009-01-16 10:38:43 +0000487}
488
489
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000490bool Object::IsMap() {
491 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000492 && HeapObject::cast(this)->map()->instance_type() == MAP_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000493}
494
495
496bool Object::IsFixedArray() {
497 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000498 && HeapObject::cast(this)->map()->instance_type() == FIXED_ARRAY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000499}
500
501
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000502bool Object::IsFixedDoubleArray() {
503 return Object::IsHeapObject()
504 && HeapObject::cast(this)->map()->instance_type() ==
505 FIXED_DOUBLE_ARRAY_TYPE;
506}
507
508
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000509bool Object::IsDescriptorArray() {
510 return IsFixedArray();
511}
512
513
kasperl@chromium.orga5551262010-12-07 12:49:48 +0000514bool Object::IsDeoptimizationInputData() {
515 // Must be a fixed array.
516 if (!IsFixedArray()) return false;
517
518 // There's no sure way to detect the difference between a fixed array and
519 // a deoptimization data array. Since this is used for asserts we can
520 // check that the length is zero or else the fixed size plus a multiple of
521 // the entry size.
522 int length = FixedArray::cast(this)->length();
523 if (length == 0) return true;
524
525 length -= DeoptimizationInputData::kFirstDeoptEntryIndex;
526 return length >= 0 &&
527 length % DeoptimizationInputData::kDeoptEntrySize == 0;
528}
529
530
531bool Object::IsDeoptimizationOutputData() {
532 if (!IsFixedArray()) return false;
533 // There's actually no way to see the difference between a fixed array and
534 // a deoptimization data array. Since this is used for asserts we can check
535 // that the length is plausible though.
536 if (FixedArray::cast(this)->length() % 2 != 0) return false;
537 return true;
538}
539
540
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000541bool Object::IsContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000542 if (Object::IsHeapObject()) {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000543 Map* map = HeapObject::cast(this)->map();
544 Heap* heap = map->GetHeap();
545 return (map == heap->function_context_map() ||
546 map == heap->catch_context_map() ||
547 map == heap->with_context_map() ||
548 map == heap->global_context_map());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000549 }
550 return false;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000551}
552
553
554bool Object::IsGlobalContext() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000555 return Object::IsHeapObject() &&
556 HeapObject::cast(this)->map() ==
557 HeapObject::cast(this)->GetHeap()->global_context_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000558}
559
560
561bool Object::IsJSFunction() {
562 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000563 && HeapObject::cast(this)->map()->instance_type() == JS_FUNCTION_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000564}
565
566
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000567template <> inline bool Is<JSFunction>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000568 return obj->IsJSFunction();
569}
570
571
572bool Object::IsCode() {
573 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000574 && HeapObject::cast(this)->map()->instance_type() == CODE_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000575}
576
577
578bool Object::IsOddball() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000579 ASSERT(HEAP->is_safe_to_read_maps());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000580 return Object::IsHeapObject()
581 && HeapObject::cast(this)->map()->instance_type() == ODDBALL_TYPE;
582}
583
584
kasperl@chromium.org2abc4502009-07-02 07:00:29 +0000585bool Object::IsJSGlobalPropertyCell() {
586 return Object::IsHeapObject()
587 && HeapObject::cast(this)->map()->instance_type()
588 == JS_GLOBAL_PROPERTY_CELL_TYPE;
589}
590
591
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000592bool Object::IsSharedFunctionInfo() {
593 return Object::IsHeapObject() &&
594 (HeapObject::cast(this)->map()->instance_type() ==
595 SHARED_FUNCTION_INFO_TYPE);
596}
597
598
599bool Object::IsJSValue() {
600 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000601 && HeapObject::cast(this)->map()->instance_type() == JS_VALUE_TYPE;
602}
603
604
605bool Object::IsJSMessageObject() {
606 return Object::IsHeapObject()
607 && (HeapObject::cast(this)->map()->instance_type() ==
608 JS_MESSAGE_OBJECT_TYPE);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000609}
610
611
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000612bool Object::IsStringWrapper() {
613 return IsJSValue() && JSValue::cast(this)->value()->IsString();
614}
615
616
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000617bool Object::IsForeign() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000618 return Object::IsHeapObject()
ager@chromium.orgea91cc52011-05-23 06:06:11 +0000619 && HeapObject::cast(this)->map()->instance_type() == FOREIGN_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000620}
621
622
623bool Object::IsBoolean() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000624 return IsOddball() &&
625 ((Oddball::cast(this)->kind() & Oddball::kNotBooleanMask) == 0);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000626}
627
628
629bool Object::IsJSArray() {
630 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000631 && HeapObject::cast(this)->map()->instance_type() == JS_ARRAY_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000632}
633
634
ager@chromium.org236ad962008-09-25 09:45:57 +0000635bool Object::IsJSRegExp() {
636 return Object::IsHeapObject()
kmillikin@chromium.org31b12772011-02-02 16:08:26 +0000637 && HeapObject::cast(this)->map()->instance_type() == JS_REGEXP_TYPE;
ager@chromium.org236ad962008-09-25 09:45:57 +0000638}
639
640
ager@chromium.orgc27e4e72008-09-04 13:52:27 +0000641template <> inline bool Is<JSArray>(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000642 return obj->IsJSArray();
643}
644
645
646bool Object::IsHashTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000647 return Object::IsHeapObject() &&
648 HeapObject::cast(this)->map() ==
649 HeapObject::cast(this)->GetHeap()->hash_table_map();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000650}
651
652
653bool Object::IsDictionary() {
whesse@chromium.org7b260152011-06-20 15:33:18 +0000654 return IsHashTable() &&
655 this != HeapObject::cast(this)->GetHeap()->symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000656}
657
658
659bool Object::IsSymbolTable() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000660 return IsHashTable() && this ==
661 HeapObject::cast(this)->GetHeap()->raw_unchecked_symbol_table();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000662}
663
664
ager@chromium.orgac091b72010-05-05 07:34:42 +0000665bool Object::IsJSFunctionResultCache() {
666 if (!IsFixedArray()) return false;
667 FixedArray* self = FixedArray::cast(this);
668 int length = self->length();
669 if (length < JSFunctionResultCache::kEntriesIndex) return false;
670 if ((length - JSFunctionResultCache::kEntriesIndex)
671 % JSFunctionResultCache::kEntrySize != 0) {
672 return false;
673 }
674#ifdef DEBUG
675 reinterpret_cast<JSFunctionResultCache*>(this)->JSFunctionResultCacheVerify();
676#endif
677 return true;
678}
679
680
ricow@chromium.org65fae842010-08-25 15:26:24 +0000681bool Object::IsNormalizedMapCache() {
682 if (!IsFixedArray()) return false;
683 if (FixedArray::cast(this)->length() != NormalizedMapCache::kEntries) {
684 return false;
685 }
686#ifdef DEBUG
687 reinterpret_cast<NormalizedMapCache*>(this)->NormalizedMapCacheVerify();
688#endif
689 return true;
690}
691
692
kasperl@chromium.orgb9123622008-09-17 14:05:56 +0000693bool Object::IsCompilationCacheTable() {
694 return IsHashTable();
ager@chromium.org9258b6b2008-09-11 09:11:10 +0000695}
696
697
ager@chromium.orgce5e87b2010-03-10 10:24:18 +0000698bool Object::IsCodeCacheHashTable() {
699 return IsHashTable();
700}
701
702
jkummerow@chromium.orge297f592011-06-08 10:05:15 +0000703bool Object::IsPolymorphicCodeCacheHashTable() {
704 return IsHashTable();
705}
706
707
ager@chromium.org236ad962008-09-25 09:45:57 +0000708bool Object::IsMapCache() {
709 return IsHashTable();
710}
711
712
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000713bool Object::IsPrimitive() {
714 return IsOddball() || IsNumber() || IsString();
715}
716
717
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000718bool Object::IsJSGlobalProxy() {
719 bool result = IsHeapObject() &&
720 (HeapObject::cast(this)->map()->instance_type() ==
721 JS_GLOBAL_PROXY_TYPE);
722 ASSERT(!result || IsAccessCheckNeeded());
723 return result;
724}
725
726
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000727bool Object::IsGlobalObject() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000728 if (!IsHeapObject()) return false;
729
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000730 InstanceType type = HeapObject::cast(this)->map()->instance_type();
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000731 return type == JS_GLOBAL_OBJECT_TYPE ||
732 type == JS_BUILTINS_OBJECT_TYPE;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000733}
734
735
736bool Object::IsJSGlobalObject() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000737 return IsHeapObject() &&
738 (HeapObject::cast(this)->map()->instance_type() ==
739 JS_GLOBAL_OBJECT_TYPE);
740}
741
742
743bool Object::IsJSBuiltinsObject() {
744 return IsHeapObject() &&
745 (HeapObject::cast(this)->map()->instance_type() ==
746 JS_BUILTINS_OBJECT_TYPE);
747}
748
749
750bool Object::IsUndetectableObject() {
751 return IsHeapObject()
752 && HeapObject::cast(this)->map()->is_undetectable();
753}
754
755
756bool Object::IsAccessCheckNeeded() {
757 return IsHeapObject()
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000758 && HeapObject::cast(this)->map()->is_access_check_needed();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000759}
760
761
762bool Object::IsStruct() {
763 if (!IsHeapObject()) return false;
764 switch (HeapObject::cast(this)->map()->instance_type()) {
765#define MAKE_STRUCT_CASE(NAME, Name, name) case NAME##_TYPE: return true;
766 STRUCT_LIST(MAKE_STRUCT_CASE)
767#undef MAKE_STRUCT_CASE
768 default: return false;
769 }
770}
771
772
773#define MAKE_STRUCT_PREDICATE(NAME, Name, name) \
774 bool Object::Is##Name() { \
775 return Object::IsHeapObject() \
776 && HeapObject::cast(this)->map()->instance_type() == NAME##_TYPE; \
777 }
778 STRUCT_LIST(MAKE_STRUCT_PREDICATE)
779#undef MAKE_STRUCT_PREDICATE
780
781
782bool Object::IsUndefined() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000783 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kUndefined;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000784}
785
786
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000787bool Object::IsNull() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000788 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kNull;
789}
790
791
792bool Object::IsTheHole() {
793 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTheHole;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000794}
795
796
797bool Object::IsTrue() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000798 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kTrue;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000799}
800
801
802bool Object::IsFalse() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000803 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kFalse;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000804}
805
806
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000807bool Object::IsArgumentsMarker() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000808 return IsOddball() && Oddball::cast(this)->kind() == Oddball::kArgumentMarker;
kmillikin@chromium.orgd2c22f02011-01-10 08:15:37 +0000809}
810
811
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000812double Object::Number() {
813 ASSERT(IsNumber());
814 return IsSmi()
815 ? static_cast<double>(reinterpret_cast<Smi*>(this)->value())
816 : reinterpret_cast<HeapNumber*>(this)->value();
817}
818
819
lrn@chromium.org303ada72010-10-27 09:33:13 +0000820MaybeObject* Object::ToSmi() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000821 if (IsSmi()) return this;
822 if (IsHeapNumber()) {
823 double value = HeapNumber::cast(this)->value();
824 int int_value = FastD2I(value);
825 if (value == FastI2D(int_value) && Smi::IsValid(int_value)) {
826 return Smi::FromInt(int_value);
827 }
828 }
829 return Failure::Exception();
830}
831
832
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000833bool Object::HasSpecificClassOf(String* name) {
834 return this->IsJSObject() && (JSObject::cast(this)->class_name() == name);
835}
836
837
lrn@chromium.org303ada72010-10-27 09:33:13 +0000838MaybeObject* Object::GetElement(uint32_t index) {
vegorov@chromium.org5d6c1f52011-02-28 13:13:38 +0000839 // GetElement can trigger a getter which can cause allocation.
840 // This was not always the case. This ASSERT is here to catch
841 // leftover incorrect uses.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000842 ASSERT(HEAP->IsAllocationAllowed());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000843 return GetElementWithReceiver(this, index);
844}
845
846
lrn@chromium.org303ada72010-10-27 09:33:13 +0000847Object* Object::GetElementNoExceptionThrown(uint32_t index) {
848 MaybeObject* maybe = GetElementWithReceiver(this, index);
849 ASSERT(!maybe->IsFailure());
850 Object* result = NULL; // Initialization to please compiler.
851 maybe->ToObject(&result);
852 return result;
853}
854
855
856MaybeObject* Object::GetProperty(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000857 PropertyAttributes attributes;
858 return GetPropertyWithReceiver(this, key, &attributes);
859}
860
861
lrn@chromium.org303ada72010-10-27 09:33:13 +0000862MaybeObject* Object::GetProperty(String* key, PropertyAttributes* attributes) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000863 return GetPropertyWithReceiver(this, key, attributes);
864}
865
866
867#define FIELD_ADDR(p, offset) \
868 (reinterpret_cast<byte*>(p) + offset - kHeapObjectTag)
869
870#define READ_FIELD(p, offset) \
871 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)))
872
873#define WRITE_FIELD(p, offset, value) \
874 (*reinterpret_cast<Object**>(FIELD_ADDR(p, offset)) = value)
875
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000876// TODO(isolates): Pass heap in to these macros.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000877#define WRITE_BARRIER(object, offset) \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000878 object->GetHeap()->RecordWrite(object->address(), offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000879
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +0000880// CONDITIONAL_WRITE_BARRIER must be issued after the actual
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000881// write due to the assert validating the written value.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000882#define CONDITIONAL_WRITE_BARRIER(heap, object, offset, mode) \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000883 if (mode == UPDATE_WRITE_BARRIER) { \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000884 heap->RecordWrite(object->address(), offset); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000885 } else { \
886 ASSERT(mode == SKIP_WRITE_BARRIER); \
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +0000887 ASSERT(heap->InNewSpace(object) || \
888 !heap->InNewSpace(READ_FIELD(object, offset)) || \
ricow@chromium.org30ce4112010-05-31 10:38:25 +0000889 Page::FromAddress(object->address())-> \
890 IsRegionDirty(object->address() + offset)); \
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +0000891 }
892
lrn@chromium.org7516f052011-03-30 08:52:27 +0000893#ifndef V8_TARGET_ARCH_MIPS
894 #define READ_DOUBLE_FIELD(p, offset) \
895 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)))
896#else // V8_TARGET_ARCH_MIPS
897 // Prevent gcc from using load-double (mips ldc1) on (possibly)
898 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000899 static inline double read_double_field(void* p, int offset) {
lrn@chromium.org7516f052011-03-30 08:52:27 +0000900 union conversion {
901 double d;
902 uint32_t u[2];
903 } c;
904 c.u[0] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)));
905 c.u[1] = (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4)));
906 return c.d;
907 }
908 #define READ_DOUBLE_FIELD(p, offset) read_double_field(p, offset)
909#endif // V8_TARGET_ARCH_MIPS
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000910
lrn@chromium.org7516f052011-03-30 08:52:27 +0000911
912#ifndef V8_TARGET_ARCH_MIPS
913 #define WRITE_DOUBLE_FIELD(p, offset, value) \
914 (*reinterpret_cast<double*>(FIELD_ADDR(p, offset)) = value)
915#else // V8_TARGET_ARCH_MIPS
916 // Prevent gcc from using store-double (mips sdc1) on (possibly)
917 // non-64-bit aligned HeapNumber::value.
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +0000918 static inline void write_double_field(void* p, int offset,
lrn@chromium.org7516f052011-03-30 08:52:27 +0000919 double value) {
920 union conversion {
921 double d;
922 uint32_t u[2];
923 } c;
924 c.d = value;
925 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset))) = c.u[0];
926 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset + 4))) = c.u[1];
927 }
928 #define WRITE_DOUBLE_FIELD(p, offset, value) \
929 write_double_field(p, offset, value)
930#endif // V8_TARGET_ARCH_MIPS
931
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000932
933#define READ_INT_FIELD(p, offset) \
934 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)))
935
936#define WRITE_INT_FIELD(p, offset, value) \
937 (*reinterpret_cast<int*>(FIELD_ADDR(p, offset)) = value)
938
ager@chromium.org3e875802009-06-29 08:26:34 +0000939#define READ_INTPTR_FIELD(p, offset) \
940 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)))
941
942#define WRITE_INTPTR_FIELD(p, offset, value) \
943 (*reinterpret_cast<intptr_t*>(FIELD_ADDR(p, offset)) = value)
944
ager@chromium.org7c537e22008-10-16 08:43:32 +0000945#define READ_UINT32_FIELD(p, offset) \
946 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)))
947
948#define WRITE_UINT32_FIELD(p, offset, value) \
949 (*reinterpret_cast<uint32_t*>(FIELD_ADDR(p, offset)) = value)
950
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000951#define READ_SHORT_FIELD(p, offset) \
952 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)))
953
954#define WRITE_SHORT_FIELD(p, offset, value) \
955 (*reinterpret_cast<uint16_t*>(FIELD_ADDR(p, offset)) = value)
956
957#define READ_BYTE_FIELD(p, offset) \
958 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)))
959
960#define WRITE_BYTE_FIELD(p, offset, value) \
961 (*reinterpret_cast<byte*>(FIELD_ADDR(p, offset)) = value)
962
963
kasperl@chromium.org9bbf9682008-10-30 11:53:07 +0000964Object** HeapObject::RawField(HeapObject* obj, int byte_offset) {
965 return &READ_FIELD(obj, byte_offset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000966}
967
968
969int Smi::value() {
ager@chromium.org18ad94b2009-09-02 08:22:29 +0000970 return Internals::SmiValue(this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000971}
972
973
974Smi* Smi::FromInt(int value) {
975 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000976 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
ager@chromium.org9085a012009-05-11 19:22:57 +0000977 intptr_t tagged_value =
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000978 (static_cast<intptr_t>(value) << smi_shift_bits) | kSmiTag;
ager@chromium.org9085a012009-05-11 19:22:57 +0000979 return reinterpret_cast<Smi*>(tagged_value);
980}
981
982
983Smi* Smi::FromIntptr(intptr_t value) {
984 ASSERT(Smi::IsValid(value));
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +0000985 int smi_shift_bits = kSmiTagSize + kSmiShiftSize;
986 return reinterpret_cast<Smi*>((value << smi_shift_bits) | kSmiTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +0000987}
988
989
990Failure::Type Failure::type() const {
991 return static_cast<Type>(value() & kFailureTypeTagMask);
992}
993
994
995bool Failure::IsInternalError() const {
996 return type() == INTERNAL_ERROR;
997}
998
999
1000bool Failure::IsOutOfMemoryException() const {
1001 return type() == OUT_OF_MEMORY_EXCEPTION;
1002}
1003
1004
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001005AllocationSpace Failure::allocation_space() const {
1006 ASSERT_EQ(RETRY_AFTER_GC, type());
1007 return static_cast<AllocationSpace>((value() >> kFailureTypeTagSize)
1008 & kSpaceTagMask);
1009}
1010
1011
1012Failure* Failure::InternalError() {
1013 return Construct(INTERNAL_ERROR);
1014}
1015
1016
1017Failure* Failure::Exception() {
1018 return Construct(EXCEPTION);
1019}
1020
sgjesse@chromium.orgc81c8942009-08-21 10:54:26 +00001021
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001022Failure* Failure::OutOfMemoryException() {
1023 return Construct(OUT_OF_MEMORY_EXCEPTION);
1024}
1025
1026
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001027intptr_t Failure::value() const {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001028 return static_cast<intptr_t>(
1029 reinterpret_cast<uintptr_t>(this) >> kFailureTagSize);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001030}
1031
1032
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001033Failure* Failure::RetryAfterGC() {
1034 return RetryAfterGC(NEW_SPACE);
1035}
1036
1037
1038Failure* Failure::RetryAfterGC(AllocationSpace space) {
1039 ASSERT((space & ~kSpaceTagMask) == 0);
1040 return Construct(RETRY_AFTER_GC, space);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001041}
1042
1043
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001044Failure* Failure::Construct(Type type, intptr_t value) {
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001045 uintptr_t info =
1046 (static_cast<uintptr_t>(value) << kFailureTypeTagSize) | type;
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001047 ASSERT(((info << kFailureTagSize) >> kFailureTagSize) == info);
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001048 return reinterpret_cast<Failure*>((info << kFailureTagSize) | kFailureTag);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001049}
1050
1051
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001052bool Smi::IsValid(intptr_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001053#ifdef DEBUG
1054 bool in_range = (value >= kMinValue) && (value <= kMaxValue);
1055#endif
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001056
1057#ifdef V8_TARGET_ARCH_X64
1058 // To be representable as a long smi, the value must be a 32-bit integer.
1059 bool result = (value == static_cast<int32_t>(value));
1060#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001061 // To be representable as an tagged small integer, the two
1062 // most-significant bits of 'value' must be either 00 or 11 due to
1063 // sign-extension. To check this we add 01 to the two
1064 // most-significant bits, and check if the most-significant bit is 0
1065 //
1066 // CAUTION: The original code below:
1067 // bool result = ((value + 0x40000000) & 0x80000000) == 0;
1068 // may lead to incorrect results according to the C language spec, and
1069 // in fact doesn't work correctly with gcc4.1.1 in some cases: The
1070 // compiler may produce undefined results in case of signed integer
1071 // overflow. The computation must be done w/ unsigned ints.
christian.plesner.hansen@gmail.com9d58c2b2009-10-16 11:48:38 +00001072 bool result = (static_cast<uintptr_t>(value + 0x40000000U) < 0x80000000U);
ager@chromium.org9085a012009-05-11 19:22:57 +00001073#endif
ager@chromium.org9085a012009-05-11 19:22:57 +00001074 ASSERT(result == in_range);
1075 return result;
1076}
1077
1078
kasper.lund7276f142008-07-30 08:49:36 +00001079MapWord MapWord::FromMap(Map* map) {
1080 return MapWord(reinterpret_cast<uintptr_t>(map));
1081}
1082
1083
1084Map* MapWord::ToMap() {
1085 return reinterpret_cast<Map*>(value_);
1086}
1087
1088
1089bool MapWord::IsForwardingAddress() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001090 return HAS_SMI_TAG(reinterpret_cast<Object*>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001091}
1092
1093
1094MapWord MapWord::FromForwardingAddress(HeapObject* object) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001095 Address raw = reinterpret_cast<Address>(object) - kHeapObjectTag;
1096 return MapWord(reinterpret_cast<uintptr_t>(raw));
kasper.lund7276f142008-07-30 08:49:36 +00001097}
1098
1099
1100HeapObject* MapWord::ToForwardingAddress() {
1101 ASSERT(IsForwardingAddress());
ager@chromium.org7c537e22008-10-16 08:43:32 +00001102 return HeapObject::FromAddress(reinterpret_cast<Address>(value_));
kasper.lund7276f142008-07-30 08:49:36 +00001103}
1104
1105
1106bool MapWord::IsMarked() {
1107 return (value_ & kMarkingMask) == 0;
1108}
1109
1110
1111void MapWord::SetMark() {
1112 value_ &= ~kMarkingMask;
1113}
1114
1115
1116void MapWord::ClearMark() {
1117 value_ |= kMarkingMask;
1118}
1119
1120
1121bool MapWord::IsOverflowed() {
1122 return (value_ & kOverflowMask) != 0;
1123}
1124
1125
1126void MapWord::SetOverflow() {
1127 value_ |= kOverflowMask;
1128}
1129
1130
1131void MapWord::ClearOverflow() {
1132 value_ &= ~kOverflowMask;
1133}
1134
1135
1136MapWord MapWord::EncodeAddress(Address map_address, int offset) {
1137 // Offset is the distance in live bytes from the first live object in the
1138 // same page. The offset between two objects in the same page should not
1139 // exceed the object area size of a page.
1140 ASSERT(0 <= offset && offset < Page::kObjectAreaSize);
1141
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001142 uintptr_t compact_offset = offset >> kObjectAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001143 ASSERT(compact_offset < (1 << kForwardingOffsetBits));
1144
1145 Page* map_page = Page::FromAddress(map_address);
1146 ASSERT_MAP_PAGE_INDEX(map_page->mc_page_index);
1147
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001148 uintptr_t map_page_offset =
1149 map_page->Offset(map_address) >> kMapAlignmentBits;
kasper.lund7276f142008-07-30 08:49:36 +00001150
1151 uintptr_t encoding =
1152 (compact_offset << kForwardingOffsetShift) |
1153 (map_page_offset << kMapPageOffsetShift) |
1154 (map_page->mc_page_index << kMapPageIndexShift);
1155 return MapWord(encoding);
1156}
1157
1158
1159Address MapWord::DecodeMapAddress(MapSpace* map_space) {
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001160 int map_page_index =
1161 static_cast<int>((value_ & kMapPageIndexMask) >> kMapPageIndexShift);
kasper.lund7276f142008-07-30 08:49:36 +00001162 ASSERT_MAP_PAGE_INDEX(map_page_index);
1163
ager@chromium.orgab99eea2009-08-25 07:05:41 +00001164 int map_page_offset = static_cast<int>(
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001165 ((value_ & kMapPageOffsetMask) >> kMapPageOffsetShift) <<
1166 kMapAlignmentBits);
kasper.lund7276f142008-07-30 08:49:36 +00001167
1168 return (map_space->PageAddress(map_page_index) + map_page_offset);
1169}
1170
1171
1172int MapWord::DecodeOffset() {
1173 // The offset field is represented in the kForwardingOffsetBits
1174 // most-significant bits.
ager@chromium.orgc4c92722009-11-18 14:12:51 +00001175 uintptr_t offset = (value_ >> kForwardingOffsetShift) << kObjectAlignmentBits;
1176 ASSERT(offset < static_cast<uintptr_t>(Page::kObjectAreaSize));
1177 return static_cast<int>(offset);
kasper.lund7276f142008-07-30 08:49:36 +00001178}
1179
1180
1181MapWord MapWord::FromEncodedAddress(Address address) {
1182 return MapWord(reinterpret_cast<uintptr_t>(address));
1183}
1184
1185
1186Address MapWord::ToEncodedAddress() {
1187 return reinterpret_cast<Address>(value_);
1188}
1189
1190
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001191#ifdef DEBUG
1192void HeapObject::VerifyObjectField(int offset) {
1193 VerifyPointer(READ_FIELD(this, offset));
1194}
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001195
1196void HeapObject::VerifySmiField(int offset) {
1197 ASSERT(READ_FIELD(this, offset)->IsSmi());
1198}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001199#endif
1200
1201
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001202Heap* HeapObject::GetHeap() {
1203 // During GC, the map pointer in HeapObject is used in various ways that
1204 // prevent us from retrieving Heap from the map.
1205 // Assert that we are not in GC, implement GC code in a way that it doesn't
1206 // pull heap from the map.
1207 ASSERT(HEAP->is_safe_to_read_maps());
1208 return map()->heap();
1209}
1210
1211
1212Isolate* HeapObject::GetIsolate() {
1213 return GetHeap()->isolate();
1214}
1215
1216
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001217Map* HeapObject::map() {
kasper.lund7276f142008-07-30 08:49:36 +00001218 return map_word().ToMap();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001219}
1220
1221
1222void HeapObject::set_map(Map* value) {
kasper.lund7276f142008-07-30 08:49:36 +00001223 set_map_word(MapWord::FromMap(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001224}
1225
1226
kasper.lund7276f142008-07-30 08:49:36 +00001227MapWord HeapObject::map_word() {
1228 return MapWord(reinterpret_cast<uintptr_t>(READ_FIELD(this, kMapOffset)));
1229}
1230
1231
1232void HeapObject::set_map_word(MapWord map_word) {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001233 // WRITE_FIELD does not invoke write barrier, but there is no need
kasper.lund7276f142008-07-30 08:49:36 +00001234 // here.
1235 WRITE_FIELD(this, kMapOffset, reinterpret_cast<Object*>(map_word.value_));
1236}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001237
1238
1239HeapObject* HeapObject::FromAddress(Address address) {
1240 ASSERT_TAG_ALIGNED(address);
1241 return reinterpret_cast<HeapObject*>(address + kHeapObjectTag);
1242}
1243
1244
1245Address HeapObject::address() {
1246 return reinterpret_cast<Address>(this) - kHeapObjectTag;
1247}
1248
1249
1250int HeapObject::Size() {
1251 return SizeFromMap(map());
1252}
1253
1254
1255void HeapObject::IteratePointers(ObjectVisitor* v, int start, int end) {
1256 v->VisitPointers(reinterpret_cast<Object**>(FIELD_ADDR(this, start)),
1257 reinterpret_cast<Object**>(FIELD_ADDR(this, end)));
1258}
1259
1260
1261void HeapObject::IteratePointer(ObjectVisitor* v, int offset) {
1262 v->VisitPointer(reinterpret_cast<Object**>(FIELD_ADDR(this, offset)));
1263}
1264
1265
kasper.lund7276f142008-07-30 08:49:36 +00001266bool HeapObject::IsMarked() {
1267 return map_word().IsMarked();
1268}
1269
1270
1271void HeapObject::SetMark() {
1272 ASSERT(!IsMarked());
1273 MapWord first_word = map_word();
1274 first_word.SetMark();
1275 set_map_word(first_word);
1276}
1277
1278
1279void HeapObject::ClearMark() {
1280 ASSERT(IsMarked());
1281 MapWord first_word = map_word();
1282 first_word.ClearMark();
1283 set_map_word(first_word);
1284}
1285
1286
1287bool HeapObject::IsOverflowed() {
1288 return map_word().IsOverflowed();
1289}
1290
1291
1292void HeapObject::SetOverflow() {
1293 MapWord first_word = map_word();
1294 first_word.SetOverflow();
1295 set_map_word(first_word);
1296}
1297
1298
1299void HeapObject::ClearOverflow() {
1300 ASSERT(IsOverflowed());
1301 MapWord first_word = map_word();
1302 first_word.ClearOverflow();
1303 set_map_word(first_word);
1304}
1305
1306
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001307double HeapNumber::value() {
1308 return READ_DOUBLE_FIELD(this, kValueOffset);
1309}
1310
1311
1312void HeapNumber::set_value(double value) {
1313 WRITE_DOUBLE_FIELD(this, kValueOffset, value);
1314}
1315
1316
whesse@chromium.orgcec079d2010-03-22 14:44:04 +00001317int HeapNumber::get_exponent() {
1318 return ((READ_INT_FIELD(this, kExponentOffset) & kExponentMask) >>
1319 kExponentShift) - kExponentBias;
1320}
1321
1322
1323int HeapNumber::get_sign() {
1324 return READ_INT_FIELD(this, kExponentOffset) & kSignMask;
1325}
1326
1327
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001328ACCESSORS(JSObject, properties, FixedArray, kPropertiesOffset)
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001329
1330
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001331HeapObject* JSObject::elements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001332 Object* array = READ_FIELD(this, kElementsOffset);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001333 ASSERT(array->HasValidElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001334 return reinterpret_cast<HeapObject*>(array);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001335}
1336
1337
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001338void JSObject::set_elements(HeapObject* value, WriteBarrierMode mode) {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001339 ASSERT(map()->has_fast_elements() ==
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001340 (value->map() == GetHeap()->fixed_array_map() ||
1341 value->map() == GetHeap()->fixed_cow_array_map()));
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001342 ASSERT(value->HasValidElements());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001343 WRITE_FIELD(this, kElementsOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001344 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kElementsOffset, mode);
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00001345}
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001346
1347
1348void JSObject::initialize_properties() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001349 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1350 WRITE_FIELD(this, kPropertiesOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001351}
1352
1353
1354void JSObject::initialize_elements() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001355 ASSERT(map()->has_fast_elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001356 ASSERT(!GetHeap()->InNewSpace(GetHeap()->empty_fixed_array()));
1357 WRITE_FIELD(this, kElementsOffset, GetHeap()->empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001358}
1359
1360
lrn@chromium.org303ada72010-10-27 09:33:13 +00001361MaybeObject* JSObject::ResetElements() {
1362 Object* obj;
1363 { MaybeObject* maybe_obj = map()->GetFastElementsMap();
1364 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1365 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00001366 set_map(Map::cast(obj));
1367 initialize_elements();
1368 return this;
1369}
1370
1371
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001372ACCESSORS(Oddball, to_string, String, kToStringOffset)
1373ACCESSORS(Oddball, to_number, Object, kToNumberOffset)
1374
1375
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001376byte Oddball::kind() {
1377 return READ_BYTE_FIELD(this, kKindOffset);
1378}
1379
1380
1381void Oddball::set_kind(byte value) {
1382 WRITE_BYTE_FIELD(this, kKindOffset, value);
1383}
1384
1385
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001386Object* JSGlobalPropertyCell::value() {
1387 return READ_FIELD(this, kValueOffset);
1388}
1389
1390
1391void JSGlobalPropertyCell::set_value(Object* val, WriteBarrierMode ignored) {
1392 // The write barrier is not used for global property cells.
1393 ASSERT(!val->IsJSGlobalPropertyCell());
1394 WRITE_FIELD(this, kValueOffset, val);
1395}
1396
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00001397
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001398int JSObject::GetHeaderSize() {
kasperl@chromium.orge959c182009-07-27 08:59:04 +00001399 InstanceType type = map()->instance_type();
1400 // Check for the most common kind of JavaScript object before
1401 // falling into the generic switch. This speeds up the internal
1402 // field operations considerably on average.
1403 if (type == JS_OBJECT_TYPE) return JSObject::kHeaderSize;
1404 switch (type) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001405 case JS_GLOBAL_PROXY_TYPE:
1406 return JSGlobalProxy::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001407 case JS_GLOBAL_OBJECT_TYPE:
1408 return JSGlobalObject::kSize;
1409 case JS_BUILTINS_OBJECT_TYPE:
1410 return JSBuiltinsObject::kSize;
1411 case JS_FUNCTION_TYPE:
1412 return JSFunction::kSize;
1413 case JS_VALUE_TYPE:
1414 return JSValue::kSize;
1415 case JS_ARRAY_TYPE:
1416 return JSValue::kSize;
ager@chromium.org236ad962008-09-25 09:45:57 +00001417 case JS_REGEXP_TYPE:
1418 return JSValue::kSize;
ager@chromium.org32912102009-01-16 10:38:43 +00001419 case JS_CONTEXT_EXTENSION_OBJECT_TYPE:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001420 return JSObject::kHeaderSize;
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00001421 case JS_MESSAGE_OBJECT_TYPE:
1422 return JSMessageObject::kSize;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001423 default:
1424 UNREACHABLE();
1425 return 0;
1426 }
1427}
1428
1429
1430int JSObject::GetInternalFieldCount() {
1431 ASSERT(1 << kPointerSizeLog2 == kPointerSize);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001432 // Make sure to adjust for the number of in-object properties. These
1433 // properties do contribute to the size, but are not internal fields.
1434 return ((Size() - GetHeaderSize()) >> kPointerSizeLog2) -
1435 map()->inobject_properties();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001436}
1437
1438
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001439int JSObject::GetInternalFieldOffset(int index) {
1440 ASSERT(index < GetInternalFieldCount() && index >= 0);
1441 return GetHeaderSize() + (kPointerSize * index);
1442}
1443
1444
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001445Object* JSObject::GetInternalField(int index) {
1446 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001447 // Internal objects do follow immediately after the header, whereas in-object
1448 // properties are at the end of the object. Therefore there is no need
1449 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001450 return READ_FIELD(this, GetHeaderSize() + (kPointerSize * index));
1451}
1452
1453
1454void JSObject::SetInternalField(int index, Object* value) {
1455 ASSERT(index < GetInternalFieldCount() && index >= 0);
ager@chromium.org7c537e22008-10-16 08:43:32 +00001456 // Internal objects do follow immediately after the header, whereas in-object
1457 // properties are at the end of the object. Therefore there is no need
1458 // to adjust the index here.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001459 int offset = GetHeaderSize() + (kPointerSize * index);
1460 WRITE_FIELD(this, offset, value);
1461 WRITE_BARRIER(this, offset);
1462}
1463
1464
ager@chromium.org7c537e22008-10-16 08:43:32 +00001465// Access fast-case object properties at index. The use of these routines
1466// is needed to correctly distinguish between properties stored in-object and
1467// properties stored in the properties array.
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001468Object* JSObject::FastPropertyAt(int index) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001469 // Adjust for the number of properties stored in the object.
1470 index -= map()->inobject_properties();
1471 if (index < 0) {
1472 int offset = map()->instance_size() + (index * kPointerSize);
1473 return READ_FIELD(this, offset);
1474 } else {
1475 ASSERT(index < properties()->length());
1476 return properties()->get(index);
1477 }
1478}
1479
1480
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001481Object* JSObject::FastPropertyAtPut(int index, Object* value) {
ager@chromium.org7c537e22008-10-16 08:43:32 +00001482 // Adjust for the number of properties stored in the object.
1483 index -= map()->inobject_properties();
1484 if (index < 0) {
1485 int offset = map()->instance_size() + (index * kPointerSize);
1486 WRITE_FIELD(this, offset, value);
1487 WRITE_BARRIER(this, offset);
1488 } else {
1489 ASSERT(index < properties()->length());
1490 properties()->set(index, value);
1491 }
1492 return value;
1493}
1494
1495
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001496int JSObject::GetInObjectPropertyOffset(int index) {
1497 // Adjust for the number of properties stored in the object.
1498 index -= map()->inobject_properties();
1499 ASSERT(index < 0);
1500 return map()->instance_size() + (index * kPointerSize);
1501}
1502
1503
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001504Object* JSObject::InObjectPropertyAt(int index) {
1505 // Adjust for the number of properties stored in the object.
1506 index -= map()->inobject_properties();
1507 ASSERT(index < 0);
1508 int offset = map()->instance_size() + (index * kPointerSize);
1509 return READ_FIELD(this, offset);
1510}
1511
1512
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001513Object* JSObject::InObjectPropertyAtPut(int index,
1514 Object* value,
1515 WriteBarrierMode mode) {
1516 // Adjust for the number of properties stored in the object.
1517 index -= map()->inobject_properties();
1518 ASSERT(index < 0);
1519 int offset = map()->instance_size() + (index * kPointerSize);
1520 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001521 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001522 return value;
1523}
1524
1525
1526
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00001527void JSObject::InitializeBody(int object_size, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001528 ASSERT(!value->IsHeapObject() || !GetHeap()->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001529 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001530 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001531 }
1532}
1533
1534
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00001535bool JSObject::HasFastProperties() {
1536 return !properties()->IsDictionary();
1537}
1538
1539
1540int JSObject::MaxFastProperties() {
1541 // Allow extra fast properties if the object has more than
1542 // kMaxFastProperties in-object properties. When this is the case,
1543 // it is very unlikely that the object is being used as a dictionary
1544 // and there is a good chance that allowing more map transitions
1545 // will be worth it.
1546 return Max(map()->inobject_properties(), kMaxFastProperties);
1547}
1548
1549
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001550void Struct::InitializeBody(int object_size) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001551 Object* value = GetHeap()->undefined_value();
ager@chromium.org236ad962008-09-25 09:45:57 +00001552 for (int offset = kHeaderSize; offset < object_size; offset += kPointerSize) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001553 WRITE_FIELD(this, offset, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001554 }
1555}
1556
1557
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001558bool Object::ToArrayIndex(uint32_t* index) {
1559 if (IsSmi()) {
1560 int value = Smi::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001561 if (value < 0) return false;
1562 *index = value;
1563 return true;
1564 }
ricow@chromium.org30ce4112010-05-31 10:38:25 +00001565 if (IsHeapNumber()) {
1566 double value = HeapNumber::cast(this)->value();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001567 uint32_t uint_value = static_cast<uint32_t>(value);
1568 if (value == static_cast<double>(uint_value)) {
1569 *index = uint_value;
1570 return true;
1571 }
1572 }
1573 return false;
1574}
1575
1576
1577bool Object::IsStringObjectWithCharacterAt(uint32_t index) {
1578 if (!this->IsJSValue()) return false;
1579
1580 JSValue* js_value = JSValue::cast(this);
1581 if (!js_value->value()->IsString()) return false;
1582
1583 String* str = String::cast(js_value->value());
1584 if (index >= (uint32_t)str->length()) return false;
1585
1586 return true;
1587}
1588
1589
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001590FixedArrayBase* FixedArrayBase::cast(Object* object) {
1591 ASSERT(object->IsFixedArray() || object->IsFixedDoubleArray());
1592 return reinterpret_cast<FixedArrayBase*>(object);
1593}
1594
1595
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001596Object* FixedArray::get(int index) {
1597 ASSERT(index >= 0 && index < this->length());
1598 return READ_FIELD(this, kHeaderSize + index * kPointerSize);
1599}
1600
1601
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001602void FixedArray::set(int index, Smi* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001603 ASSERT(map() != HEAP->fixed_cow_array_map());
ager@chromium.orga74f0da2008-12-03 16:05:52 +00001604 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1605 int offset = kHeaderSize + index * kPointerSize;
1606 WRITE_FIELD(this, offset, value);
1607}
1608
1609
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001610void FixedArray::set(int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001611 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001612 ASSERT(index >= 0 && index < this->length());
1613 int offset = kHeaderSize + index * kPointerSize;
1614 WRITE_FIELD(this, offset, value);
1615 WRITE_BARRIER(this, offset);
1616}
1617
1618
svenpanne@chromium.org84bcc552011-07-18 09:50:57 +00001619inline bool FixedDoubleArray::is_the_hole_nan(double value) {
1620 return BitCast<uint64_t, double>(value) == kHoleNanInt64;
1621}
1622
1623
1624inline double FixedDoubleArray::hole_nan_as_double() {
1625 return BitCast<double, uint64_t>(kHoleNanInt64);
1626}
1627
1628
1629inline double FixedDoubleArray::canonical_not_the_hole_nan_as_double() {
1630 ASSERT(BitCast<uint64_t>(OS::nan_value()) != kHoleNanInt64);
1631 ASSERT((BitCast<uint64_t>(OS::nan_value()) >> 32) != kHoleNanUpper32);
1632 return OS::nan_value();
1633}
1634
1635
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00001636double FixedDoubleArray::get(int index) {
1637 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1638 map() != HEAP->fixed_array_map());
1639 ASSERT(index >= 0 && index < this->length());
1640 double result = READ_DOUBLE_FIELD(this, kHeaderSize + index * kDoubleSize);
1641 ASSERT(!is_the_hole_nan(result));
1642 return result;
1643}
1644
1645
1646void FixedDoubleArray::set(int index, double value) {
1647 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1648 map() != HEAP->fixed_array_map());
1649 int offset = kHeaderSize + index * kDoubleSize;
1650 if (isnan(value)) value = canonical_not_the_hole_nan_as_double();
1651 WRITE_DOUBLE_FIELD(this, offset, value);
1652}
1653
1654
1655void FixedDoubleArray::set_the_hole(int index) {
1656 ASSERT(map() != HEAP->fixed_cow_array_map() &&
1657 map() != HEAP->fixed_array_map());
1658 int offset = kHeaderSize + index * kDoubleSize;
1659 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1660}
1661
1662
1663bool FixedDoubleArray::is_the_hole(int index) {
1664 int offset = kHeaderSize + index * kDoubleSize;
1665 return is_the_hole_nan(READ_DOUBLE_FIELD(this, offset));
1666}
1667
1668
1669void FixedDoubleArray::Initialize(FixedDoubleArray* from) {
1670 int old_length = from->length();
1671 ASSERT(old_length < length());
1672 OS::MemCopy(FIELD_ADDR(this, kHeaderSize),
1673 FIELD_ADDR(from, kHeaderSize),
1674 old_length * kDoubleSize);
1675 int offset = kHeaderSize + old_length * kDoubleSize;
1676 for (int current = from->length(); current < length(); ++current) {
1677 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1678 offset += kDoubleSize;
1679 }
1680}
1681
1682
1683void FixedDoubleArray::Initialize(FixedArray* from) {
1684 int old_length = from->length();
1685 ASSERT(old_length < length());
1686 for (int i = 0; i < old_length; i++) {
1687 Object* hole_or_object = from->get(i);
1688 if (hole_or_object->IsTheHole()) {
1689 set_the_hole(i);
1690 } else {
1691 set(i, hole_or_object->Number());
1692 }
1693 }
1694 int offset = kHeaderSize + old_length * kDoubleSize;
1695 for (int current = from->length(); current < length(); ++current) {
1696 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1697 offset += kDoubleSize;
1698 }
1699}
1700
1701
1702void FixedDoubleArray::Initialize(NumberDictionary* from) {
1703 int offset = kHeaderSize;
1704 for (int current = 0; current < length(); ++current) {
1705 WRITE_DOUBLE_FIELD(this, offset, hole_nan_as_double());
1706 offset += kDoubleSize;
1707 }
1708 for (int i = 0; i < from->Capacity(); i++) {
1709 Object* key = from->KeyAt(i);
1710 if (key->IsNumber()) {
1711 uint32_t entry = static_cast<uint32_t>(key->Number());
1712 set(entry, from->ValueAt(i)->Number());
1713 }
1714 }
1715}
1716
1717
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00001718WriteBarrierMode HeapObject::GetWriteBarrierMode(const AssertNoAllocation&) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001719 if (GetHeap()->InNewSpace(this)) return SKIP_WRITE_BARRIER;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001720 return UPDATE_WRITE_BARRIER;
1721}
1722
1723
1724void FixedArray::set(int index,
1725 Object* value,
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001726 WriteBarrierMode mode) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001727 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001728 ASSERT(index >= 0 && index < this->length());
1729 int offset = kHeaderSize + index * kPointerSize;
1730 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001731 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, offset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001732}
1733
1734
1735void FixedArray::fast_set(FixedArray* array, int index, Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001736 ASSERT(array->map() != HEAP->raw_unchecked_fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001737 ASSERT(index >= 0 && index < array->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001738 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001739 WRITE_FIELD(array, kHeaderSize + index * kPointerSize, value);
1740}
1741
1742
1743void FixedArray::set_undefined(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001744 ASSERT(map() != HEAP->fixed_cow_array_map());
1745 set_undefined(GetHeap(), index);
1746}
1747
1748
1749void FixedArray::set_undefined(Heap* heap, int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001750 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001751 ASSERT(!heap->InNewSpace(heap->undefined_value()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001752 WRITE_FIELD(this, kHeaderSize + index * kPointerSize,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001753 heap->undefined_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001754}
1755
1756
ager@chromium.org236ad962008-09-25 09:45:57 +00001757void FixedArray::set_null(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001758 set_null(GetHeap(), index);
1759}
1760
1761
1762void FixedArray::set_null(Heap* heap, int index) {
ager@chromium.org236ad962008-09-25 09:45:57 +00001763 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001764 ASSERT(!heap->InNewSpace(heap->null_value()));
1765 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ager@chromium.org236ad962008-09-25 09:45:57 +00001766}
1767
1768
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001769void FixedArray::set_the_hole(int index) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001770 ASSERT(map() != HEAP->fixed_cow_array_map());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001771 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001772 ASSERT(!HEAP->InNewSpace(HEAP->the_hole_value()));
1773 WRITE_FIELD(this,
1774 kHeaderSize + index * kPointerSize,
1775 GetHeap()->the_hole_value());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001776}
1777
1778
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001779void FixedArray::set_unchecked(int index, Smi* value) {
1780 ASSERT(reinterpret_cast<Object*>(value)->IsSmi());
1781 int offset = kHeaderSize + index * kPointerSize;
1782 WRITE_FIELD(this, offset, value);
1783}
1784
1785
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001786void FixedArray::set_unchecked(Heap* heap,
1787 int index,
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001788 Object* value,
1789 WriteBarrierMode mode) {
1790 int offset = kHeaderSize + index * kPointerSize;
1791 WRITE_FIELD(this, offset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001792 CONDITIONAL_WRITE_BARRIER(heap, this, offset, mode);
whesse@chromium.org4a5224e2010-10-20 12:37:07 +00001793}
1794
1795
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001796void FixedArray::set_null_unchecked(Heap* heap, int index) {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001797 ASSERT(index >= 0 && index < this->length());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001798 ASSERT(!HEAP->InNewSpace(heap->null_value()));
1799 WRITE_FIELD(this, kHeaderSize + index * kPointerSize, heap->null_value());
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00001800}
1801
1802
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00001803Object** FixedArray::data_start() {
1804 return HeapObject::RawField(this, kHeaderSize);
1805}
1806
1807
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001808bool DescriptorArray::IsEmpty() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00001809 ASSERT(this->IsSmi() ||
1810 this->length() > kFirstIndex ||
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001811 this == HEAP->empty_descriptor_array());
danno@chromium.org40cb8782011-05-25 07:58:50 +00001812 return this->IsSmi() || length() <= kFirstIndex;
1813}
1814
1815
1816int DescriptorArray::bit_field3_storage() {
1817 Object* storage = READ_FIELD(this, kBitField3StorageOffset);
1818 return Smi::cast(storage)->value();
1819}
1820
1821void DescriptorArray::set_bit_field3_storage(int value) {
1822 ASSERT(!IsEmpty());
1823 WRITE_FIELD(this, kBitField3StorageOffset, Smi::FromInt(value));
mads.s.ager@gmail.com9a4089a2008-09-01 08:55:01 +00001824}
1825
1826
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001827void DescriptorArray::fast_swap(FixedArray* array, int first, int second) {
1828 Object* tmp = array->get(first);
1829 fast_set(array, first, array->get(second));
1830 fast_set(array, second, tmp);
1831}
1832
1833
1834int DescriptorArray::Search(String* name) {
1835 SLOW_ASSERT(IsSortedNoDuplicates());
1836
1837 // Check for empty descriptor array.
1838 int nof = number_of_descriptors();
1839 if (nof == 0) return kNotFound;
1840
1841 // Fast case: do linear search for small arrays.
1842 const int kMaxElementsForLinearSearch = 8;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00001843 if (StringShape(name).IsSymbol() && nof < kMaxElementsForLinearSearch) {
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00001844 return LinearSearch(name, nof);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001845 }
1846
1847 // Slow case: perform binary search.
1848 return BinarySearch(name, 0, nof - 1);
1849}
1850
1851
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001852int DescriptorArray::SearchWithCache(String* name) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001853 int number = GetIsolate()->descriptor_lookup_cache()->Lookup(this, name);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001854 if (number == DescriptorLookupCache::kAbsent) {
1855 number = Search(name);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001856 GetIsolate()->descriptor_lookup_cache()->Update(this, name, number);
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00001857 }
1858 return number;
1859}
1860
1861
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001862String* DescriptorArray::GetKey(int descriptor_number) {
1863 ASSERT(descriptor_number < number_of_descriptors());
1864 return String::cast(get(ToKeyIndex(descriptor_number)));
1865}
1866
1867
1868Object* DescriptorArray::GetValue(int descriptor_number) {
1869 ASSERT(descriptor_number < number_of_descriptors());
1870 return GetContentArray()->get(ToValueIndex(descriptor_number));
1871}
1872
1873
1874Smi* DescriptorArray::GetDetails(int descriptor_number) {
1875 ASSERT(descriptor_number < number_of_descriptors());
1876 return Smi::cast(GetContentArray()->get(ToDetailsIndex(descriptor_number)));
1877}
1878
1879
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001880PropertyType DescriptorArray::GetType(int descriptor_number) {
1881 ASSERT(descriptor_number < number_of_descriptors());
1882 return PropertyDetails(GetDetails(descriptor_number)).type();
1883}
1884
1885
1886int DescriptorArray::GetFieldIndex(int descriptor_number) {
1887 return Descriptor::IndexFromValue(GetValue(descriptor_number));
1888}
1889
1890
1891JSFunction* DescriptorArray::GetConstantFunction(int descriptor_number) {
1892 return JSFunction::cast(GetValue(descriptor_number));
1893}
1894
1895
1896Object* DescriptorArray::GetCallbacksObject(int descriptor_number) {
1897 ASSERT(GetType(descriptor_number) == CALLBACKS);
1898 return GetValue(descriptor_number);
1899}
1900
1901
1902AccessorDescriptor* DescriptorArray::GetCallbacks(int descriptor_number) {
1903 ASSERT(GetType(descriptor_number) == CALLBACKS);
ager@chromium.orgea91cc52011-05-23 06:06:11 +00001904 Foreign* p = Foreign::cast(GetCallbacksObject(descriptor_number));
1905 return reinterpret_cast<AccessorDescriptor*>(p->address());
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001906}
1907
1908
1909bool DescriptorArray::IsProperty(int descriptor_number) {
1910 return GetType(descriptor_number) < FIRST_PHANTOM_PROPERTY_TYPE;
1911}
1912
1913
1914bool DescriptorArray::IsTransition(int descriptor_number) {
1915 PropertyType t = GetType(descriptor_number);
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00001916 return t == MAP_TRANSITION || t == CONSTANT_TRANSITION ||
1917 t == EXTERNAL_ARRAY_TRANSITION;
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001918}
1919
1920
1921bool DescriptorArray::IsNullDescriptor(int descriptor_number) {
1922 return GetType(descriptor_number) == NULL_DESCRIPTOR;
1923}
1924
1925
1926bool DescriptorArray::IsDontEnum(int descriptor_number) {
1927 return PropertyDetails(GetDetails(descriptor_number)).IsDontEnum();
1928}
1929
1930
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001931void DescriptorArray::Get(int descriptor_number, Descriptor* desc) {
1932 desc->Init(GetKey(descriptor_number),
1933 GetValue(descriptor_number),
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00001934 PropertyDetails(GetDetails(descriptor_number)));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001935}
1936
1937
1938void DescriptorArray::Set(int descriptor_number, Descriptor* desc) {
1939 // Range check.
1940 ASSERT(descriptor_number < number_of_descriptors());
1941
sgjesse@chromium.org846fb742009-12-18 08:56:33 +00001942 // Make sure none of the elements in desc are in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001943 ASSERT(!HEAP->InNewSpace(desc->GetKey()));
1944 ASSERT(!HEAP->InNewSpace(desc->GetValue()));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001945
1946 fast_set(this, ToKeyIndex(descriptor_number), desc->GetKey());
1947 FixedArray* content_array = GetContentArray();
1948 fast_set(content_array, ToValueIndex(descriptor_number), desc->GetValue());
1949 fast_set(content_array, ToDetailsIndex(descriptor_number),
1950 desc->GetDetails().AsSmi());
1951}
1952
1953
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00001954void DescriptorArray::CopyFrom(int index, DescriptorArray* src, int src_index) {
1955 Descriptor desc;
1956 src->Get(src_index, &desc);
1957 Set(index, &desc);
1958}
1959
1960
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001961void DescriptorArray::Swap(int first, int second) {
1962 fast_swap(this, ToKeyIndex(first), ToKeyIndex(second));
1963 FixedArray* content_array = GetContentArray();
1964 fast_swap(content_array, ToValueIndex(first), ToValueIndex(second));
1965 fast_swap(content_array, ToDetailsIndex(first), ToDetailsIndex(second));
1966}
1967
1968
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00001969template<typename Shape, typename Key>
1970int HashTable<Shape, Key>::FindEntry(Key key) {
1971 return FindEntry(GetIsolate(), key);
1972}
1973
1974
1975// Find entry for key otherwise return kNotFound.
1976template<typename Shape, typename Key>
1977int HashTable<Shape, Key>::FindEntry(Isolate* isolate, Key key) {
1978 uint32_t capacity = Capacity();
1979 uint32_t entry = FirstProbe(Shape::Hash(key), capacity);
1980 uint32_t count = 1;
1981 // EnsureCapacity will guarantee the hash table is never full.
1982 while (true) {
1983 Object* element = KeyAt(entry);
1984 if (element == isolate->heap()->undefined_value()) break; // Empty entry.
1985 if (element != isolate->heap()->null_value() &&
1986 Shape::IsMatch(key, element)) return entry;
1987 entry = NextProbe(entry, count++, capacity);
1988 }
1989 return kNotFound;
1990}
1991
1992
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00001993bool NumberDictionary::requires_slow_elements() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00001994 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00001995 if (!max_index_object->IsSmi()) return false;
1996 return 0 !=
1997 (Smi::cast(max_index_object)->value() & kRequiresSlowElementsMask);
1998}
1999
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002000uint32_t NumberDictionary::max_number_key() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002001 ASSERT(!requires_slow_elements());
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002002 Object* max_index_object = get(kMaxNumberKeyIndex);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002003 if (!max_index_object->IsSmi()) return 0;
2004 uint32_t value = static_cast<uint32_t>(Smi::cast(max_index_object)->value());
2005 return value >> kRequiresSlowElementsTagSize;
2006}
2007
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002008void NumberDictionary::set_requires_slow_elements() {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00002009 set(kMaxNumberKeyIndex, Smi::FromInt(kRequiresSlowElementsMask));
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002010}
2011
2012
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002013// ------------------------------------
2014// Cast operations
2015
2016
2017CAST_ACCESSOR(FixedArray)
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002018CAST_ACCESSOR(FixedDoubleArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002019CAST_ACCESSOR(DescriptorArray)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002020CAST_ACCESSOR(DeoptimizationInputData)
2021CAST_ACCESSOR(DeoptimizationOutputData)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002022CAST_ACCESSOR(SymbolTable)
ager@chromium.orgac091b72010-05-05 07:34:42 +00002023CAST_ACCESSOR(JSFunctionResultCache)
ricow@chromium.org65fae842010-08-25 15:26:24 +00002024CAST_ACCESSOR(NormalizedMapCache)
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00002025CAST_ACCESSOR(CompilationCacheTable)
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002026CAST_ACCESSOR(CodeCacheHashTable)
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00002027CAST_ACCESSOR(PolymorphicCodeCacheHashTable)
ager@chromium.org236ad962008-09-25 09:45:57 +00002028CAST_ACCESSOR(MapCache)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002029CAST_ACCESSOR(String)
2030CAST_ACCESSOR(SeqString)
ager@chromium.org7c537e22008-10-16 08:43:32 +00002031CAST_ACCESSOR(SeqAsciiString)
2032CAST_ACCESSOR(SeqTwoByteString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002033CAST_ACCESSOR(ConsString)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002034CAST_ACCESSOR(ExternalString)
2035CAST_ACCESSOR(ExternalAsciiString)
2036CAST_ACCESSOR(ExternalTwoByteString)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002037CAST_ACCESSOR(JSReceiver)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002038CAST_ACCESSOR(JSObject)
2039CAST_ACCESSOR(Smi)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002040CAST_ACCESSOR(HeapObject)
2041CAST_ACCESSOR(HeapNumber)
2042CAST_ACCESSOR(Oddball)
kasperl@chromium.org2abc4502009-07-02 07:00:29 +00002043CAST_ACCESSOR(JSGlobalPropertyCell)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002044CAST_ACCESSOR(SharedFunctionInfo)
2045CAST_ACCESSOR(Map)
2046CAST_ACCESSOR(JSFunction)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002047CAST_ACCESSOR(GlobalObject)
2048CAST_ACCESSOR(JSGlobalProxy)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002049CAST_ACCESSOR(JSGlobalObject)
2050CAST_ACCESSOR(JSBuiltinsObject)
2051CAST_ACCESSOR(Code)
2052CAST_ACCESSOR(JSArray)
ager@chromium.org236ad962008-09-25 09:45:57 +00002053CAST_ACCESSOR(JSRegExp)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00002054CAST_ACCESSOR(JSProxy)
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00002055CAST_ACCESSOR(JSFunctionProxy)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002056CAST_ACCESSOR(Foreign)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002057CAST_ACCESSOR(ByteArray)
ager@chromium.org3811b432009-10-28 14:53:37 +00002058CAST_ACCESSOR(ExternalArray)
2059CAST_ACCESSOR(ExternalByteArray)
2060CAST_ACCESSOR(ExternalUnsignedByteArray)
2061CAST_ACCESSOR(ExternalShortArray)
2062CAST_ACCESSOR(ExternalUnsignedShortArray)
2063CAST_ACCESSOR(ExternalIntArray)
2064CAST_ACCESSOR(ExternalUnsignedIntArray)
2065CAST_ACCESSOR(ExternalFloatArray)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002066CAST_ACCESSOR(ExternalDoubleArray)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002067CAST_ACCESSOR(ExternalPixelArray)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002068CAST_ACCESSOR(Struct)
2069
2070
2071#define MAKE_STRUCT_CAST(NAME, Name, name) CAST_ACCESSOR(Name)
2072 STRUCT_LIST(MAKE_STRUCT_CAST)
2073#undef MAKE_STRUCT_CAST
2074
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00002075
2076template <typename Shape, typename Key>
2077HashTable<Shape, Key>* HashTable<Shape, Key>::cast(Object* obj) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002078 ASSERT(obj->IsHashTable());
2079 return reinterpret_cast<HashTable*>(obj);
2080}
2081
2082
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002083SMI_ACCESSORS(FixedArrayBase, length, kLengthOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002084SMI_ACCESSORS(ByteArray, length, kLengthOffset)
2085
lrn@chromium.orgac2828d2011-06-23 06:29:21 +00002086// TODO(1493): Investigate if it's possible to s/INT/SMI/ here (and
whesse@chromium.org7b260152011-06-20 15:33:18 +00002087// subsequently unify H{Fixed,External}ArrayLength).
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002088INT_ACCESSORS(ExternalArray, length, kLengthOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002089
2090
ager@chromium.orgac091b72010-05-05 07:34:42 +00002091SMI_ACCESSORS(String, length, kLengthOffset)
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002092
2093
2094uint32_t String::hash_field() {
2095 return READ_UINT32_FIELD(this, kHashFieldOffset);
2096}
2097
2098
2099void String::set_hash_field(uint32_t value) {
2100 WRITE_UINT32_FIELD(this, kHashFieldOffset, value);
ricow@chromium.org30ce4112010-05-31 10:38:25 +00002101#if V8_HOST_ARCH_64_BIT
2102 WRITE_UINT32_FIELD(this, kHashFieldOffset + kIntSize, 0);
2103#endif
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00002104}
2105
2106
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002107bool String::Equals(String* other) {
2108 if (other == this) return true;
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002109 if (StringShape(this).IsSymbol() && StringShape(other).IsSymbol()) {
2110 return false;
2111 }
2112 return SlowEquals(other);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002113}
2114
2115
lrn@chromium.org303ada72010-10-27 09:33:13 +00002116MaybeObject* String::TryFlatten(PretenureFlag pretenure) {
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002117 if (!StringShape(this).IsCons()) return this;
2118 ConsString* cons = ConsString::cast(this);
2119 if (cons->second()->length() == 0) return cons->first();
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00002120 return SlowTryFlatten(pretenure);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002121}
2122
2123
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002124String* String::TryFlattenGetString(PretenureFlag pretenure) {
lrn@chromium.org303ada72010-10-27 09:33:13 +00002125 MaybeObject* flat = TryFlatten(pretenure);
2126 Object* successfully_flattened;
2127 if (flat->ToObject(&successfully_flattened)) {
2128 return String::cast(successfully_flattened);
2129 }
2130 return this;
erik.corry@gmail.com9dfbea42010-05-21 12:58:28 +00002131}
2132
2133
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002134uint16_t String::Get(int index) {
2135 ASSERT(index >= 0 && index < length());
2136 switch (StringShape(this).full_representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002137 case kSeqStringTag | kAsciiStringTag:
2138 return SeqAsciiString::cast(this)->SeqAsciiStringGet(index);
2139 case kSeqStringTag | kTwoByteStringTag:
2140 return SeqTwoByteString::cast(this)->SeqTwoByteStringGet(index);
2141 case kConsStringTag | kAsciiStringTag:
2142 case kConsStringTag | kTwoByteStringTag:
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002143 return ConsString::cast(this)->ConsStringGet(index);
ager@chromium.org870a0b62008-11-04 11:43:05 +00002144 case kExternalStringTag | kAsciiStringTag:
2145 return ExternalAsciiString::cast(this)->ExternalAsciiStringGet(index);
2146 case kExternalStringTag | kTwoByteStringTag:
2147 return ExternalTwoByteString::cast(this)->ExternalTwoByteStringGet(index);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002148 default:
2149 break;
2150 }
2151
2152 UNREACHABLE();
2153 return 0;
2154}
2155
2156
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002157void String::Set(int index, uint16_t value) {
2158 ASSERT(index >= 0 && index < length());
2159 ASSERT(StringShape(this).IsSequential());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002160
ager@chromium.org5ec48922009-05-05 07:25:34 +00002161 return this->IsAsciiRepresentation()
ager@chromium.org7c537e22008-10-16 08:43:32 +00002162 ? SeqAsciiString::cast(this)->SeqAsciiStringSet(index, value)
2163 : SeqTwoByteString::cast(this)->SeqTwoByteStringSet(index, value);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002164}
2165
2166
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002167bool String::IsFlat() {
2168 switch (StringShape(this).representation_tag()) {
ager@chromium.org870a0b62008-11-04 11:43:05 +00002169 case kConsStringTag: {
2170 String* second = ConsString::cast(this)->second();
ager@chromium.org7c537e22008-10-16 08:43:32 +00002171 // Only flattened strings have second part empty.
ager@chromium.org870a0b62008-11-04 11:43:05 +00002172 return second->length() == 0;
2173 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00002174 default:
2175 return true;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002176 }
2177}
2178
2179
ager@chromium.org7c537e22008-10-16 08:43:32 +00002180uint16_t SeqAsciiString::SeqAsciiStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002181 ASSERT(index >= 0 && index < length());
2182 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2183}
2184
2185
ager@chromium.org7c537e22008-10-16 08:43:32 +00002186void SeqAsciiString::SeqAsciiStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002187 ASSERT(index >= 0 && index < length() && value <= kMaxAsciiCharCode);
2188 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize,
2189 static_cast<byte>(value));
2190}
2191
2192
ager@chromium.org7c537e22008-10-16 08:43:32 +00002193Address SeqAsciiString::GetCharsAddress() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002194 return FIELD_ADDR(this, kHeaderSize);
2195}
2196
2197
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002198char* SeqAsciiString::GetChars() {
2199 return reinterpret_cast<char*>(GetCharsAddress());
2200}
2201
2202
ager@chromium.org7c537e22008-10-16 08:43:32 +00002203Address SeqTwoByteString::GetCharsAddress() {
2204 return FIELD_ADDR(this, kHeaderSize);
2205}
2206
2207
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00002208uc16* SeqTwoByteString::GetChars() {
2209 return reinterpret_cast<uc16*>(FIELD_ADDR(this, kHeaderSize));
2210}
2211
2212
ager@chromium.org7c537e22008-10-16 08:43:32 +00002213uint16_t SeqTwoByteString::SeqTwoByteStringGet(int index) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002214 ASSERT(index >= 0 && index < length());
2215 return READ_SHORT_FIELD(this, kHeaderSize + index * kShortSize);
2216}
2217
2218
ager@chromium.org7c537e22008-10-16 08:43:32 +00002219void SeqTwoByteString::SeqTwoByteStringSet(int index, uint16_t value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002220 ASSERT(index >= 0 && index < length());
2221 WRITE_SHORT_FIELD(this, kHeaderSize + index * kShortSize, value);
2222}
2223
2224
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002225int SeqTwoByteString::SeqTwoByteStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002226 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002227}
2228
2229
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00002230int SeqAsciiString::SeqAsciiStringSize(InstanceType instance_type) {
ager@chromium.orgac091b72010-05-05 07:34:42 +00002231 return SizeFor(length());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002232}
2233
2234
ager@chromium.org870a0b62008-11-04 11:43:05 +00002235String* ConsString::first() {
2236 return String::cast(READ_FIELD(this, kFirstOffset));
2237}
2238
2239
2240Object* ConsString::unchecked_first() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002241 return READ_FIELD(this, kFirstOffset);
2242}
2243
2244
ager@chromium.org870a0b62008-11-04 11:43:05 +00002245void ConsString::set_first(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002246 WRITE_FIELD(this, kFirstOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002247 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kFirstOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002248}
2249
2250
ager@chromium.org870a0b62008-11-04 11:43:05 +00002251String* ConsString::second() {
2252 return String::cast(READ_FIELD(this, kSecondOffset));
2253}
2254
2255
2256Object* ConsString::unchecked_second() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002257 return READ_FIELD(this, kSecondOffset);
2258}
2259
2260
ager@chromium.org870a0b62008-11-04 11:43:05 +00002261void ConsString::set_second(String* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002262 WRITE_FIELD(this, kSecondOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002263 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kSecondOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002264}
2265
2266
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002267ExternalAsciiString::Resource* ExternalAsciiString::resource() {
2268 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2269}
2270
2271
2272void ExternalAsciiString::set_resource(
2273 ExternalAsciiString::Resource* resource) {
2274 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2275}
2276
2277
2278ExternalTwoByteString::Resource* ExternalTwoByteString::resource() {
2279 return *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset));
2280}
2281
2282
2283void ExternalTwoByteString::set_resource(
2284 ExternalTwoByteString::Resource* resource) {
2285 *reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)) = resource;
2286}
2287
2288
ager@chromium.orgac091b72010-05-05 07:34:42 +00002289void JSFunctionResultCache::MakeZeroSize() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002290 set_finger_index(kEntriesIndex);
2291 set_size(kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002292}
2293
2294
2295void JSFunctionResultCache::Clear() {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002296 int cache_size = size();
ager@chromium.orgac091b72010-05-05 07:34:42 +00002297 Object** entries_start = RawField(this, OffsetOfElementAt(kEntriesIndex));
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002298 MemsetPointer(entries_start,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00002299 GetHeap()->the_hole_value(),
fschneider@chromium.orge03fb642010-11-01 12:34:09 +00002300 cache_size - kEntriesIndex);
ager@chromium.orgac091b72010-05-05 07:34:42 +00002301 MakeZeroSize();
2302}
2303
2304
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002305int JSFunctionResultCache::size() {
2306 return Smi::cast(get(kCacheSizeIndex))->value();
2307}
2308
2309
2310void JSFunctionResultCache::set_size(int size) {
2311 set(kCacheSizeIndex, Smi::FromInt(size));
2312}
2313
2314
2315int JSFunctionResultCache::finger_index() {
2316 return Smi::cast(get(kFingerIndex))->value();
2317}
2318
2319
2320void JSFunctionResultCache::set_finger_index(int finger_index) {
2321 set(kFingerIndex, Smi::FromInt(finger_index));
2322}
2323
2324
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002325byte ByteArray::get(int index) {
2326 ASSERT(index >= 0 && index < this->length());
2327 return READ_BYTE_FIELD(this, kHeaderSize + index * kCharSize);
2328}
2329
2330
2331void ByteArray::set(int index, byte value) {
2332 ASSERT(index >= 0 && index < this->length());
2333 WRITE_BYTE_FIELD(this, kHeaderSize + index * kCharSize, value);
2334}
2335
2336
2337int ByteArray::get_int(int index) {
2338 ASSERT(index >= 0 && (index * kIntSize) < this->length());
2339 return READ_INT_FIELD(this, kHeaderSize + index * kIntSize);
2340}
2341
2342
2343ByteArray* ByteArray::FromDataStartAddress(Address address) {
2344 ASSERT_TAG_ALIGNED(address);
2345 return reinterpret_cast<ByteArray*>(address - kHeaderSize + kHeapObjectTag);
2346}
2347
2348
2349Address ByteArray::GetDataStartAddress() {
2350 return reinterpret_cast<Address>(this) - kHeapObjectTag + kHeaderSize;
2351}
2352
2353
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002354uint8_t* ExternalPixelArray::external_pixel_pointer() {
2355 return reinterpret_cast<uint8_t*>(external_pointer());
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002356}
2357
2358
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002359uint8_t ExternalPixelArray::get(int index) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002360 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002361 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002362 return ptr[index];
2363}
2364
2365
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002366void ExternalPixelArray::set(int index, uint8_t value) {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002367 ASSERT((index >= 0) && (index < this->length()));
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00002368 uint8_t* ptr = external_pixel_pointer();
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00002369 ptr[index] = value;
2370}
2371
2372
ager@chromium.org3811b432009-10-28 14:53:37 +00002373void* ExternalArray::external_pointer() {
2374 intptr_t ptr = READ_INTPTR_FIELD(this, kExternalPointerOffset);
2375 return reinterpret_cast<void*>(ptr);
2376}
2377
2378
2379void ExternalArray::set_external_pointer(void* value, WriteBarrierMode mode) {
2380 intptr_t ptr = reinterpret_cast<intptr_t>(value);
2381 WRITE_INTPTR_FIELD(this, kExternalPointerOffset, ptr);
2382}
2383
2384
2385int8_t ExternalByteArray::get(int index) {
2386 ASSERT((index >= 0) && (index < this->length()));
2387 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2388 return ptr[index];
2389}
2390
2391
2392void ExternalByteArray::set(int index, int8_t value) {
2393 ASSERT((index >= 0) && (index < this->length()));
2394 int8_t* ptr = static_cast<int8_t*>(external_pointer());
2395 ptr[index] = value;
2396}
2397
2398
2399uint8_t ExternalUnsignedByteArray::get(int index) {
2400 ASSERT((index >= 0) && (index < this->length()));
2401 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2402 return ptr[index];
2403}
2404
2405
2406void ExternalUnsignedByteArray::set(int index, uint8_t value) {
2407 ASSERT((index >= 0) && (index < this->length()));
2408 uint8_t* ptr = static_cast<uint8_t*>(external_pointer());
2409 ptr[index] = value;
2410}
2411
2412
2413int16_t ExternalShortArray::get(int index) {
2414 ASSERT((index >= 0) && (index < this->length()));
2415 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2416 return ptr[index];
2417}
2418
2419
2420void ExternalShortArray::set(int index, int16_t value) {
2421 ASSERT((index >= 0) && (index < this->length()));
2422 int16_t* ptr = static_cast<int16_t*>(external_pointer());
2423 ptr[index] = value;
2424}
2425
2426
2427uint16_t ExternalUnsignedShortArray::get(int index) {
2428 ASSERT((index >= 0) && (index < this->length()));
2429 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2430 return ptr[index];
2431}
2432
2433
2434void ExternalUnsignedShortArray::set(int index, uint16_t value) {
2435 ASSERT((index >= 0) && (index < this->length()));
2436 uint16_t* ptr = static_cast<uint16_t*>(external_pointer());
2437 ptr[index] = value;
2438}
2439
2440
2441int32_t ExternalIntArray::get(int index) {
2442 ASSERT((index >= 0) && (index < this->length()));
2443 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2444 return ptr[index];
2445}
2446
2447
2448void ExternalIntArray::set(int index, int32_t value) {
2449 ASSERT((index >= 0) && (index < this->length()));
2450 int32_t* ptr = static_cast<int32_t*>(external_pointer());
2451 ptr[index] = value;
2452}
2453
2454
2455uint32_t ExternalUnsignedIntArray::get(int index) {
2456 ASSERT((index >= 0) && (index < this->length()));
2457 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2458 return ptr[index];
2459}
2460
2461
2462void ExternalUnsignedIntArray::set(int index, uint32_t value) {
2463 ASSERT((index >= 0) && (index < this->length()));
2464 uint32_t* ptr = static_cast<uint32_t*>(external_pointer());
2465 ptr[index] = value;
2466}
2467
2468
2469float ExternalFloatArray::get(int index) {
2470 ASSERT((index >= 0) && (index < this->length()));
2471 float* ptr = static_cast<float*>(external_pointer());
2472 return ptr[index];
2473}
2474
2475
2476void ExternalFloatArray::set(int index, float value) {
2477 ASSERT((index >= 0) && (index < this->length()));
2478 float* ptr = static_cast<float*>(external_pointer());
2479 ptr[index] = value;
2480}
2481
ager@chromium.org6a2b0aa2010-07-13 20:58:03 +00002482
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002483double ExternalDoubleArray::get(int index) {
2484 ASSERT((index >= 0) && (index < this->length()));
2485 double* ptr = static_cast<double*>(external_pointer());
2486 return ptr[index];
2487}
2488
2489
2490void ExternalDoubleArray::set(int index, double value) {
2491 ASSERT((index >= 0) && (index < this->length()));
2492 double* ptr = static_cast<double*>(external_pointer());
2493 ptr[index] = value;
2494}
2495
2496
ager@chromium.org5b2fbee2010-09-08 06:38:15 +00002497int Map::visitor_id() {
2498 return READ_BYTE_FIELD(this, kVisitorIdOffset);
2499}
2500
2501
2502void Map::set_visitor_id(int id) {
2503 ASSERT(0 <= id && id < 256);
2504 WRITE_BYTE_FIELD(this, kVisitorIdOffset, static_cast<byte>(id));
2505}
2506
ager@chromium.org3811b432009-10-28 14:53:37 +00002507
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002508int Map::instance_size() {
ager@chromium.org7c537e22008-10-16 08:43:32 +00002509 return READ_BYTE_FIELD(this, kInstanceSizeOffset) << kPointerSizeLog2;
2510}
2511
2512
2513int Map::inobject_properties() {
2514 return READ_BYTE_FIELD(this, kInObjectPropertiesOffset);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002515}
2516
2517
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002518int Map::pre_allocated_property_fields() {
2519 return READ_BYTE_FIELD(this, kPreAllocatedPropertyFieldsOffset);
2520}
2521
2522
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002523int HeapObject::SizeFromMap(Map* map) {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002524 int instance_size = map->instance_size();
2525 if (instance_size != kVariableSizeSentinel) return instance_size;
2526 // We can ignore the "symbol" bit becase it is only set for symbols
2527 // and implies a string type.
2528 int instance_type = static_cast<int>(map->instance_type()) & ~kIsSymbolMask;
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002529 // Only inline the most frequent cases.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002530 if (instance_type == FIXED_ARRAY_TYPE) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00002531 return FixedArray::BodyDescriptor::SizeOf(map, this);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002532 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002533 if (instance_type == ASCII_STRING_TYPE) {
2534 return SeqAsciiString::SizeFor(
2535 reinterpret_cast<SeqAsciiString*>(this)->length());
2536 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00002537 if (instance_type == BYTE_ARRAY_TYPE) {
2538 return reinterpret_cast<ByteArray*>(this)->ByteArraySize();
2539 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002540 if (instance_type == STRING_TYPE) {
2541 return SeqTwoByteString::SizeFor(
2542 reinterpret_cast<SeqTwoByteString*>(this)->length());
2543 }
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00002544 if (instance_type == FIXED_DOUBLE_ARRAY_TYPE) {
2545 return FixedDoubleArray::SizeFor(
2546 reinterpret_cast<FixedDoubleArray*>(this)->length());
2547 }
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00002548 ASSERT(instance_type == CODE_TYPE);
2549 return reinterpret_cast<Code*>(this)->CodeSize();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002550}
2551
2552
2553void Map::set_instance_size(int value) {
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002554 ASSERT_EQ(0, value & (kPointerSize - 1));
ager@chromium.org7c537e22008-10-16 08:43:32 +00002555 value >>= kPointerSizeLog2;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002556 ASSERT(0 <= value && value < 256);
2557 WRITE_BYTE_FIELD(this, kInstanceSizeOffset, static_cast<byte>(value));
2558}
2559
2560
ager@chromium.org7c537e22008-10-16 08:43:32 +00002561void Map::set_inobject_properties(int value) {
2562 ASSERT(0 <= value && value < 256);
2563 WRITE_BYTE_FIELD(this, kInObjectPropertiesOffset, static_cast<byte>(value));
2564}
2565
2566
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00002567void Map::set_pre_allocated_property_fields(int value) {
2568 ASSERT(0 <= value && value < 256);
2569 WRITE_BYTE_FIELD(this,
2570 kPreAllocatedPropertyFieldsOffset,
2571 static_cast<byte>(value));
2572}
2573
2574
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002575InstanceType Map::instance_type() {
2576 return static_cast<InstanceType>(READ_BYTE_FIELD(this, kInstanceTypeOffset));
2577}
2578
2579
2580void Map::set_instance_type(InstanceType value) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002581 WRITE_BYTE_FIELD(this, kInstanceTypeOffset, value);
2582}
2583
2584
2585int Map::unused_property_fields() {
2586 return READ_BYTE_FIELD(this, kUnusedPropertyFieldsOffset);
2587}
2588
2589
2590void Map::set_unused_property_fields(int value) {
2591 WRITE_BYTE_FIELD(this, kUnusedPropertyFieldsOffset, Min(value, 255));
2592}
2593
2594
2595byte Map::bit_field() {
2596 return READ_BYTE_FIELD(this, kBitFieldOffset);
2597}
2598
2599
2600void Map::set_bit_field(byte value) {
2601 WRITE_BYTE_FIELD(this, kBitFieldOffset, value);
2602}
2603
2604
ager@chromium.org3a37e9b2009-04-27 09:26:21 +00002605byte Map::bit_field2() {
2606 return READ_BYTE_FIELD(this, kBitField2Offset);
2607}
2608
2609
2610void Map::set_bit_field2(byte value) {
2611 WRITE_BYTE_FIELD(this, kBitField2Offset, value);
2612}
2613
2614
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002615void Map::set_non_instance_prototype(bool value) {
2616 if (value) {
2617 set_bit_field(bit_field() | (1 << kHasNonInstancePrototype));
2618 } else {
2619 set_bit_field(bit_field() & ~(1 << kHasNonInstancePrototype));
2620 }
2621}
2622
2623
2624bool Map::has_non_instance_prototype() {
2625 return ((1 << kHasNonInstancePrototype) & bit_field()) != 0;
2626}
2627
2628
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00002629void Map::set_function_with_prototype(bool value) {
2630 if (value) {
2631 set_bit_field2(bit_field2() | (1 << kFunctionWithPrototype));
2632 } else {
2633 set_bit_field2(bit_field2() & ~(1 << kFunctionWithPrototype));
2634 }
2635}
2636
2637
2638bool Map::function_with_prototype() {
2639 return ((1 << kFunctionWithPrototype) & bit_field2()) != 0;
2640}
2641
2642
ager@chromium.org870a0b62008-11-04 11:43:05 +00002643void Map::set_is_access_check_needed(bool access_check_needed) {
2644 if (access_check_needed) {
2645 set_bit_field(bit_field() | (1 << kIsAccessCheckNeeded));
2646 } else {
2647 set_bit_field(bit_field() & ~(1 << kIsAccessCheckNeeded));
2648 }
2649}
2650
2651
2652bool Map::is_access_check_needed() {
2653 return ((1 << kIsAccessCheckNeeded) & bit_field()) != 0;
2654}
2655
2656
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002657void Map::set_is_extensible(bool value) {
2658 if (value) {
2659 set_bit_field2(bit_field2() | (1 << kIsExtensible));
2660 } else {
2661 set_bit_field2(bit_field2() & ~(1 << kIsExtensible));
2662 }
2663}
2664
2665bool Map::is_extensible() {
2666 return ((1 << kIsExtensible) & bit_field2()) != 0;
2667}
2668
2669
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002670void Map::set_attached_to_shared_function_info(bool value) {
2671 if (value) {
2672 set_bit_field2(bit_field2() | (1 << kAttachedToSharedFunctionInfo));
2673 } else {
2674 set_bit_field2(bit_field2() & ~(1 << kAttachedToSharedFunctionInfo));
2675 }
2676}
2677
2678bool Map::attached_to_shared_function_info() {
2679 return ((1 << kAttachedToSharedFunctionInfo) & bit_field2()) != 0;
2680}
2681
2682
2683void Map::set_is_shared(bool value) {
2684 if (value) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002685 set_bit_field3(bit_field3() | (1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002686 } else {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002687 set_bit_field3(bit_field3() & ~(1 << kIsShared));
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002688 }
2689}
2690
2691bool Map::is_shared() {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002692 return ((1 << kIsShared) & bit_field3()) != 0;
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00002693}
2694
2695
2696JSFunction* Map::unchecked_constructor() {
2697 return reinterpret_cast<JSFunction*>(READ_FIELD(this, kConstructorOffset));
2698}
2699
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002700
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00002701FixedArray* Map::unchecked_prototype_transitions() {
2702 return reinterpret_cast<FixedArray*>(
2703 READ_FIELD(this, kPrototypeTransitionsOffset));
2704}
2705
2706
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002707Code::Flags Code::flags() {
2708 return static_cast<Flags>(READ_INT_FIELD(this, kFlagsOffset));
2709}
2710
2711
2712void Code::set_flags(Code::Flags flags) {
ager@chromium.orga74f0da2008-12-03 16:05:52 +00002713 STATIC_ASSERT(Code::NUMBER_OF_KINDS <= (kFlagsKindMask >> kFlagsKindShift)+1);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002714 // Make sure that all call stubs have an arguments count.
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002715 ASSERT((ExtractKindFromFlags(flags) != CALL_IC &&
2716 ExtractKindFromFlags(flags) != KEYED_CALL_IC) ||
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002717 ExtractArgumentsCountFromFlags(flags) >= 0);
2718 WRITE_INT_FIELD(this, kFlagsOffset, flags);
2719}
2720
2721
2722Code::Kind Code::kind() {
2723 return ExtractKindFromFlags(flags());
2724}
2725
2726
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002727InLoopFlag Code::ic_in_loop() {
2728 return ExtractICInLoopFromFlags(flags());
2729}
2730
2731
kasper.lund7276f142008-07-30 08:49:36 +00002732InlineCacheState Code::ic_state() {
2733 InlineCacheState result = ExtractICStateFromFlags(flags());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002734 // Only allow uninitialized or debugger states for non-IC code
2735 // objects. This is used in the debugger to determine whether or not
2736 // a call to code object has been replaced with a debug break call.
2737 ASSERT(is_inline_cache_stub() ||
2738 result == UNINITIALIZED ||
2739 result == DEBUG_BREAK ||
2740 result == DEBUG_PREPARE_STEP_IN);
2741 return result;
2742}
2743
2744
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002745Code::ExtraICState Code::extra_ic_state() {
2746 ASSERT(is_inline_cache_stub());
2747 return ExtractExtraICStateFromFlags(flags());
2748}
2749
2750
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002751PropertyType Code::type() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002752 return ExtractTypeFromFlags(flags());
2753}
2754
2755
2756int Code::arguments_count() {
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00002757 ASSERT(is_call_stub() || is_keyed_call_stub() || kind() == STUB);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002758 return ExtractArgumentsCountFromFlags(flags());
2759}
2760
2761
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002762int Code::major_key() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002763 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002764 kind() == UNARY_OP_IC ||
2765 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002766 kind() == COMPARE_IC ||
2767 kind() == TO_BOOLEAN_IC);
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002768 return READ_BYTE_FIELD(this, kStubMajorKeyOffset);
kasper.lund7276f142008-07-30 08:49:36 +00002769}
2770
2771
ricow@chromium.orgd236f4d2010-09-01 06:52:08 +00002772void Code::set_major_key(int major) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002773 ASSERT(kind() == STUB ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002774 kind() == UNARY_OP_IC ||
2775 kind() == BINARY_OP_IC ||
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002776 kind() == COMPARE_IC ||
2777 kind() == TO_BOOLEAN_IC);
kasper.lund7276f142008-07-30 08:49:36 +00002778 ASSERT(0 <= major && major < 256);
2779 WRITE_BYTE_FIELD(this, kStubMajorKeyOffset, major);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002780}
2781
2782
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002783bool Code::optimizable() {
2784 ASSERT(kind() == FUNCTION);
2785 return READ_BYTE_FIELD(this, kOptimizableOffset) == 1;
2786}
2787
2788
2789void Code::set_optimizable(bool value) {
2790 ASSERT(kind() == FUNCTION);
2791 WRITE_BYTE_FIELD(this, kOptimizableOffset, value ? 1 : 0);
2792}
2793
2794
2795bool Code::has_deoptimization_support() {
2796 ASSERT(kind() == FUNCTION);
2797 return READ_BYTE_FIELD(this, kHasDeoptimizationSupportOffset) == 1;
2798}
2799
2800
2801void Code::set_has_deoptimization_support(bool value) {
2802 ASSERT(kind() == FUNCTION);
2803 WRITE_BYTE_FIELD(this, kHasDeoptimizationSupportOffset, value ? 1 : 0);
2804}
2805
2806
2807int Code::allow_osr_at_loop_nesting_level() {
2808 ASSERT(kind() == FUNCTION);
2809 return READ_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset);
2810}
2811
2812
2813void Code::set_allow_osr_at_loop_nesting_level(int level) {
2814 ASSERT(kind() == FUNCTION);
2815 ASSERT(level >= 0 && level <= kMaxLoopNestingMarker);
2816 WRITE_BYTE_FIELD(this, kAllowOSRAtLoopNestingLevelOffset, level);
2817}
2818
2819
2820unsigned Code::stack_slots() {
2821 ASSERT(kind() == OPTIMIZED_FUNCTION);
2822 return READ_UINT32_FIELD(this, kStackSlotsOffset);
2823}
2824
2825
2826void Code::set_stack_slots(unsigned slots) {
2827 ASSERT(kind() == OPTIMIZED_FUNCTION);
2828 WRITE_UINT32_FIELD(this, kStackSlotsOffset, slots);
2829}
2830
2831
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002832unsigned Code::safepoint_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002833 ASSERT(kind() == OPTIMIZED_FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002834 return READ_UINT32_FIELD(this, kSafepointTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002835}
2836
2837
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002838void Code::set_safepoint_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002839 ASSERT(kind() == OPTIMIZED_FUNCTION);
2840 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002841 WRITE_UINT32_FIELD(this, kSafepointTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002842}
2843
2844
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002845unsigned Code::stack_check_table_offset() {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002846 ASSERT(kind() == FUNCTION);
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002847 return READ_UINT32_FIELD(this, kStackCheckTableOffsetOffset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002848}
2849
2850
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002851void Code::set_stack_check_table_offset(unsigned offset) {
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002852 ASSERT(kind() == FUNCTION);
2853 ASSERT(IsAligned(offset, static_cast<unsigned>(kIntSize)));
ricow@chromium.org83aa5492011-02-07 12:42:56 +00002854 WRITE_UINT32_FIELD(this, kStackCheckTableOffsetOffset, offset);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002855}
2856
2857
2858CheckType Code::check_type() {
2859 ASSERT(is_call_stub() || is_keyed_call_stub());
2860 byte type = READ_BYTE_FIELD(this, kCheckTypeOffset);
2861 return static_cast<CheckType>(type);
2862}
2863
2864
2865void Code::set_check_type(CheckType value) {
2866 ASSERT(is_call_stub() || is_keyed_call_stub());
2867 WRITE_BYTE_FIELD(this, kCheckTypeOffset, value);
2868}
2869
2870
danno@chromium.org40cb8782011-05-25 07:58:50 +00002871byte Code::unary_op_type() {
2872 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002873 return READ_BYTE_FIELD(this, kUnaryOpTypeOffset);
2874}
2875
2876
danno@chromium.org40cb8782011-05-25 07:58:50 +00002877void Code::set_unary_op_type(byte value) {
2878 ASSERT(is_unary_op_stub());
sgjesse@chromium.org8e8294a2011-05-02 14:30:53 +00002879 WRITE_BYTE_FIELD(this, kUnaryOpTypeOffset, value);
2880}
2881
2882
danno@chromium.org40cb8782011-05-25 07:58:50 +00002883byte Code::binary_op_type() {
2884 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002885 return READ_BYTE_FIELD(this, kBinaryOpTypeOffset);
2886}
2887
2888
danno@chromium.org40cb8782011-05-25 07:58:50 +00002889void Code::set_binary_op_type(byte value) {
2890 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002891 WRITE_BYTE_FIELD(this, kBinaryOpTypeOffset, value);
2892}
2893
2894
danno@chromium.org40cb8782011-05-25 07:58:50 +00002895byte Code::binary_op_result_type() {
2896 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002897 return READ_BYTE_FIELD(this, kBinaryOpReturnTypeOffset);
2898}
2899
2900
danno@chromium.org40cb8782011-05-25 07:58:50 +00002901void Code::set_binary_op_result_type(byte value) {
2902 ASSERT(is_binary_op_stub());
kasperl@chromium.orga5551262010-12-07 12:49:48 +00002903 WRITE_BYTE_FIELD(this, kBinaryOpReturnTypeOffset, value);
2904}
2905
2906
2907byte Code::compare_state() {
2908 ASSERT(is_compare_ic_stub());
2909 return READ_BYTE_FIELD(this, kCompareStateOffset);
2910}
2911
2912
2913void Code::set_compare_state(byte value) {
2914 ASSERT(is_compare_ic_stub());
2915 WRITE_BYTE_FIELD(this, kCompareStateOffset, value);
2916}
2917
2918
ricow@chromium.org9fa09672011-07-25 11:05:35 +00002919byte Code::to_boolean_state() {
2920 ASSERT(is_to_boolean_ic_stub());
2921 return READ_BYTE_FIELD(this, kToBooleanTypeOffset);
2922}
2923
2924
2925void Code::set_to_boolean_state(byte value) {
2926 ASSERT(is_to_boolean_ic_stub());
2927 WRITE_BYTE_FIELD(this, kToBooleanTypeOffset, value);
2928}
2929
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002930bool Code::is_inline_cache_stub() {
2931 Kind kind = this->kind();
2932 return kind >= FIRST_IC_KIND && kind <= LAST_IC_KIND;
2933}
2934
2935
2936Code::Flags Code::ComputeFlags(Kind kind,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002937 InLoopFlag in_loop,
kasper.lund7276f142008-07-30 08:49:36 +00002938 InlineCacheState ic_state,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002939 ExtraICState extra_ic_state,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002940 PropertyType type,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002941 int argc,
2942 InlineCacheHolderFlag holder) {
danno@chromium.org40cb8782011-05-25 07:58:50 +00002943 // Extra IC state is only allowed for call IC stubs or for store IC
2944 // stubs.
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002945 ASSERT(extra_ic_state == kNoExtraICState ||
danno@chromium.org40cb8782011-05-25 07:58:50 +00002946 (kind == CALL_IC) ||
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00002947 (kind == STORE_IC) ||
ager@chromium.orgea91cc52011-05-23 06:06:11 +00002948 (kind == KEYED_STORE_IC));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002949 // Compute the bit mask.
2950 int bits = kind << kFlagsKindShift;
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002951 if (in_loop) bits |= kFlagsICInLoopMask;
kasper.lund7276f142008-07-30 08:49:36 +00002952 bits |= ic_state << kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002953 bits |= type << kFlagsTypeShift;
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002954 bits |= extra_ic_state << kFlagsExtraICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002955 bits |= argc << kFlagsArgumentsCountShift;
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002956 if (holder == PROTOTYPE_MAP) bits |= kFlagsCacheInPrototypeMapMask;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002957 // Cast to flags and validate result before returning it.
2958 Flags result = static_cast<Flags>(bits);
2959 ASSERT(ExtractKindFromFlags(result) == kind);
kasper.lund7276f142008-07-30 08:49:36 +00002960 ASSERT(ExtractICStateFromFlags(result) == ic_state);
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002961 ASSERT(ExtractICInLoopFromFlags(result) == in_loop);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002962 ASSERT(ExtractTypeFromFlags(result) == type);
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002963 ASSERT(ExtractExtraICStateFromFlags(result) == extra_ic_state);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002964 ASSERT(ExtractArgumentsCountFromFlags(result) == argc);
2965 return result;
2966}
2967
2968
2969Code::Flags Code::ComputeMonomorphicFlags(Kind kind,
2970 PropertyType type,
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002971 ExtraICState extra_ic_state,
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00002972 InlineCacheHolderFlag holder,
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002973 InLoopFlag in_loop,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002974 int argc) {
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002975 return ComputeFlags(
2976 kind, in_loop, MONOMORPHIC, extra_ic_state, type, argc, holder);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002977}
2978
2979
2980Code::Kind Code::ExtractKindFromFlags(Flags flags) {
2981 int bits = (flags & kFlagsKindMask) >> kFlagsKindShift;
2982 return static_cast<Kind>(bits);
2983}
2984
2985
kasper.lund7276f142008-07-30 08:49:36 +00002986InlineCacheState Code::ExtractICStateFromFlags(Flags flags) {
2987 int bits = (flags & kFlagsICStateMask) >> kFlagsICStateShift;
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00002988 return static_cast<InlineCacheState>(bits);
2989}
2990
2991
erik.corry@gmail.com0511e242011-01-19 11:11:08 +00002992Code::ExtraICState Code::ExtractExtraICStateFromFlags(Flags flags) {
2993 int bits = (flags & kFlagsExtraICStateMask) >> kFlagsExtraICStateShift;
2994 return static_cast<ExtraICState>(bits);
2995}
2996
2997
kasperl@chromium.org71affb52009-05-26 05:44:31 +00002998InLoopFlag Code::ExtractICInLoopFromFlags(Flags flags) {
2999 int bits = (flags & kFlagsICInLoopMask);
3000 return bits != 0 ? IN_LOOP : NOT_IN_LOOP;
3001}
3002
3003
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003004PropertyType Code::ExtractTypeFromFlags(Flags flags) {
3005 int bits = (flags & kFlagsTypeMask) >> kFlagsTypeShift;
3006 return static_cast<PropertyType>(bits);
3007}
3008
3009
3010int Code::ExtractArgumentsCountFromFlags(Flags flags) {
3011 return (flags & kFlagsArgumentsCountMask) >> kFlagsArgumentsCountShift;
3012}
3013
3014
kmillikin@chromium.org69ea3962010-07-05 11:01:40 +00003015InlineCacheHolderFlag Code::ExtractCacheHolderFromFlags(Flags flags) {
3016 int bits = (flags & kFlagsCacheInPrototypeMapMask);
3017 return bits != 0 ? PROTOTYPE_MAP : OWN_MAP;
3018}
3019
3020
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003021Code::Flags Code::RemoveTypeFromFlags(Flags flags) {
3022 int bits = flags & ~kFlagsTypeMask;
3023 return static_cast<Flags>(bits);
3024}
3025
3026
ager@chromium.org8bb60582008-12-11 12:02:20 +00003027Code* Code::GetCodeFromTargetAddress(Address address) {
3028 HeapObject* code = HeapObject::FromAddress(address - Code::kHeaderSize);
3029 // GetCodeFromTargetAddress might be called when marking objects during mark
3030 // sweep. reinterpret_cast is therefore used instead of the more appropriate
3031 // Code::cast. Code::cast does not work when the object's map is
3032 // marked.
3033 Code* result = reinterpret_cast<Code*>(code);
3034 return result;
3035}
3036
3037
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003038Isolate* Map::isolate() {
3039 return heap()->isolate();
3040}
3041
3042
3043Heap* Map::heap() {
3044 // NOTE: address() helper is not used to save one instruction.
3045 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
3046 ASSERT(heap != NULL);
3047 ASSERT(heap->isolate() == Isolate::Current());
3048 return heap;
3049}
3050
3051
kmillikin@chromium.orgc36ce6e2011-04-04 08:25:31 +00003052Heap* Code::heap() {
3053 // NOTE: address() helper is not used to save one instruction.
3054 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
3055 ASSERT(heap != NULL);
3056 ASSERT(heap->isolate() == Isolate::Current());
3057 return heap;
3058}
3059
3060
3061Isolate* Code::isolate() {
3062 return heap()->isolate();
3063}
3064
3065
3066Heap* JSGlobalPropertyCell::heap() {
3067 // NOTE: address() helper is not used to save one instruction.
3068 Heap* heap = Page::FromAddress(reinterpret_cast<Address>(this))->heap_;
3069 ASSERT(heap != NULL);
3070 ASSERT(heap->isolate() == Isolate::Current());
3071 return heap;
3072}
3073
3074
3075Isolate* JSGlobalPropertyCell::isolate() {
3076 return heap()->isolate();
3077}
3078
3079
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003080Object* Code::GetObjectFromEntryAddress(Address location_of_address) {
3081 return HeapObject::
3082 FromAddress(Memory::Address_at(location_of_address) - Code::kHeaderSize);
3083}
3084
3085
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003086Object* Map::prototype() {
3087 return READ_FIELD(this, kPrototypeOffset);
3088}
3089
3090
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003091void Map::set_prototype(Object* value, WriteBarrierMode mode) {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003092 ASSERT(value->IsNull() || value->IsJSReceiver());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003093 WRITE_FIELD(this, kPrototypeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003094 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kPrototypeOffset, mode);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003095}
3096
3097
lrn@chromium.org303ada72010-10-27 09:33:13 +00003098MaybeObject* Map::GetFastElementsMap() {
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003099 if (has_fast_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003100 Object* obj;
3101 { MaybeObject* maybe_obj = CopyDropTransitions();
3102 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3103 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003104 Map* new_map = Map::cast(obj);
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003105 new_map->set_elements_kind(JSObject::FAST_ELEMENTS);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003106 isolate()->counters()->map_to_fast_elements()->Increment();
3107 return new_map;
3108}
3109
3110
3111MaybeObject* Map::GetFastDoubleElementsMap() {
3112 if (has_fast_double_elements()) return this;
3113 Object* obj;
3114 { MaybeObject* maybe_obj = CopyDropTransitions();
3115 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3116 }
3117 Map* new_map = Map::cast(obj);
3118 new_map->set_elements_kind(JSObject::FAST_DOUBLE_ELEMENTS);
3119 isolate()->counters()->map_to_fast_double_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003120 return new_map;
3121}
3122
3123
lrn@chromium.org303ada72010-10-27 09:33:13 +00003124MaybeObject* Map::GetSlowElementsMap() {
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003125 if (!has_fast_elements() && !has_fast_double_elements()) return this;
lrn@chromium.org303ada72010-10-27 09:33:13 +00003126 Object* obj;
3127 { MaybeObject* maybe_obj = CopyDropTransitions();
3128 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
3129 }
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003130 Map* new_map = Map::cast(obj);
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003131 new_map->set_elements_kind(JSObject::DICTIONARY_ELEMENTS);
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003132 isolate()->counters()->map_to_slow_elements()->Increment();
fschneider@chromium.org40b9da32010-06-28 11:29:21 +00003133 return new_map;
3134}
3135
3136
danno@chromium.org40cb8782011-05-25 07:58:50 +00003137DescriptorArray* Map::instance_descriptors() {
3138 Object* object = READ_FIELD(this, kInstanceDescriptorsOrBitField3Offset);
3139 if (object->IsSmi()) {
3140 return HEAP->empty_descriptor_array();
3141 } else {
3142 return DescriptorArray::cast(object);
3143 }
3144}
3145
3146
3147void Map::init_instance_descriptors() {
3148 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, Smi::FromInt(0));
3149}
3150
3151
3152void Map::clear_instance_descriptors() {
3153 Object* object = READ_FIELD(this,
3154 kInstanceDescriptorsOrBitField3Offset);
3155 if (!object->IsSmi()) {
3156 WRITE_FIELD(
3157 this,
3158 kInstanceDescriptorsOrBitField3Offset,
3159 Smi::FromInt(DescriptorArray::cast(object)->bit_field3_storage()));
3160 }
3161}
3162
3163
3164void Map::set_instance_descriptors(DescriptorArray* value,
3165 WriteBarrierMode mode) {
3166 Object* object = READ_FIELD(this,
3167 kInstanceDescriptorsOrBitField3Offset);
3168 if (value == isolate()->heap()->empty_descriptor_array()) {
3169 clear_instance_descriptors();
3170 return;
3171 } else {
3172 if (object->IsSmi()) {
3173 value->set_bit_field3_storage(Smi::cast(object)->value());
3174 } else {
3175 value->set_bit_field3_storage(
3176 DescriptorArray::cast(object)->bit_field3_storage());
3177 }
3178 }
3179 ASSERT(!is_shared());
3180 WRITE_FIELD(this, kInstanceDescriptorsOrBitField3Offset, value);
3181 CONDITIONAL_WRITE_BARRIER(GetHeap(),
3182 this,
3183 kInstanceDescriptorsOrBitField3Offset,
3184 mode);
3185}
3186
3187
3188int Map::bit_field3() {
3189 Object* object = READ_FIELD(this,
3190 kInstanceDescriptorsOrBitField3Offset);
3191 if (object->IsSmi()) {
3192 return Smi::cast(object)->value();
3193 } else {
3194 return DescriptorArray::cast(object)->bit_field3_storage();
3195 }
3196}
3197
3198
3199void Map::set_bit_field3(int value) {
3200 ASSERT(Smi::IsValid(value));
3201 Object* object = READ_FIELD(this,
3202 kInstanceDescriptorsOrBitField3Offset);
3203 if (object->IsSmi()) {
3204 WRITE_FIELD(this,
3205 kInstanceDescriptorsOrBitField3Offset,
3206 Smi::FromInt(value));
3207 } else {
3208 DescriptorArray::cast(object)->set_bit_field3_storage(value);
3209 }
3210}
3211
3212
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003213ACCESSORS(Map, code_cache, Object, kCodeCacheOffset)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00003214ACCESSORS(Map, prototype_transitions, FixedArray, kPrototypeTransitionsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003215ACCESSORS(Map, constructor, Object, kConstructorOffset)
3216
3217ACCESSORS(JSFunction, shared, SharedFunctionInfo, kSharedFunctionInfoOffset)
3218ACCESSORS(JSFunction, literals, FixedArray, kLiteralsOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003219ACCESSORS_GCSAFE(JSFunction, next_function_link, Object,
3220 kNextFunctionLinkOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003221
3222ACCESSORS(GlobalObject, builtins, JSBuiltinsObject, kBuiltinsOffset)
3223ACCESSORS(GlobalObject, global_context, Context, kGlobalContextOffset)
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003224ACCESSORS(GlobalObject, global_receiver, JSObject, kGlobalReceiverOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003225
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003226ACCESSORS(JSGlobalProxy, context, Object, kContextOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003227
3228ACCESSORS(AccessorInfo, getter, Object, kGetterOffset)
3229ACCESSORS(AccessorInfo, setter, Object, kSetterOffset)
3230ACCESSORS(AccessorInfo, data, Object, kDataOffset)
3231ACCESSORS(AccessorInfo, name, Object, kNameOffset)
3232ACCESSORS(AccessorInfo, flag, Smi, kFlagOffset)
3233
3234ACCESSORS(AccessCheckInfo, named_callback, Object, kNamedCallbackOffset)
3235ACCESSORS(AccessCheckInfo, indexed_callback, Object, kIndexedCallbackOffset)
3236ACCESSORS(AccessCheckInfo, data, Object, kDataOffset)
3237
3238ACCESSORS(InterceptorInfo, getter, Object, kGetterOffset)
3239ACCESSORS(InterceptorInfo, setter, Object, kSetterOffset)
3240ACCESSORS(InterceptorInfo, query, Object, kQueryOffset)
3241ACCESSORS(InterceptorInfo, deleter, Object, kDeleterOffset)
3242ACCESSORS(InterceptorInfo, enumerator, Object, kEnumeratorOffset)
3243ACCESSORS(InterceptorInfo, data, Object, kDataOffset)
3244
3245ACCESSORS(CallHandlerInfo, callback, Object, kCallbackOffset)
3246ACCESSORS(CallHandlerInfo, data, Object, kDataOffset)
3247
3248ACCESSORS(TemplateInfo, tag, Object, kTagOffset)
3249ACCESSORS(TemplateInfo, property_list, Object, kPropertyListOffset)
3250
3251ACCESSORS(FunctionTemplateInfo, serial_number, Object, kSerialNumberOffset)
3252ACCESSORS(FunctionTemplateInfo, call_code, Object, kCallCodeOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003253ACCESSORS(FunctionTemplateInfo, property_accessors, Object,
3254 kPropertyAccessorsOffset)
3255ACCESSORS(FunctionTemplateInfo, prototype_template, Object,
3256 kPrototypeTemplateOffset)
3257ACCESSORS(FunctionTemplateInfo, parent_template, Object, kParentTemplateOffset)
3258ACCESSORS(FunctionTemplateInfo, named_property_handler, Object,
3259 kNamedPropertyHandlerOffset)
3260ACCESSORS(FunctionTemplateInfo, indexed_property_handler, Object,
3261 kIndexedPropertyHandlerOffset)
3262ACCESSORS(FunctionTemplateInfo, instance_template, Object,
3263 kInstanceTemplateOffset)
3264ACCESSORS(FunctionTemplateInfo, class_name, Object, kClassNameOffset)
3265ACCESSORS(FunctionTemplateInfo, signature, Object, kSignatureOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003266ACCESSORS(FunctionTemplateInfo, instance_call_handler, Object,
3267 kInstanceCallHandlerOffset)
3268ACCESSORS(FunctionTemplateInfo, access_check_info, Object,
3269 kAccessCheckInfoOffset)
3270ACCESSORS(FunctionTemplateInfo, flag, Smi, kFlagOffset)
ager@chromium.org04921a82011-06-27 13:21:41 +00003271ACCESSORS(FunctionTemplateInfo, prototype_attributes, Smi,
3272 kPrototypeAttributesOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003273
3274ACCESSORS(ObjectTemplateInfo, constructor, Object, kConstructorOffset)
kasper.lund212ac232008-07-16 07:07:30 +00003275ACCESSORS(ObjectTemplateInfo, internal_field_count, Object,
3276 kInternalFieldCountOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003277
3278ACCESSORS(SignatureInfo, receiver, Object, kReceiverOffset)
3279ACCESSORS(SignatureInfo, args, Object, kArgsOffset)
3280
3281ACCESSORS(TypeSwitchInfo, types, Object, kTypesOffset)
3282
3283ACCESSORS(Script, source, Object, kSourceOffset)
3284ACCESSORS(Script, name, Object, kNameOffset)
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003285ACCESSORS(Script, id, Object, kIdOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003286ACCESSORS(Script, line_offset, Smi, kLineOffsetOffset)
3287ACCESSORS(Script, column_offset, Smi, kColumnOffsetOffset)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003288ACCESSORS(Script, data, Object, kDataOffset)
ager@chromium.org9085a012009-05-11 19:22:57 +00003289ACCESSORS(Script, context_data, Object, kContextOffset)
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003290ACCESSORS(Script, wrapper, Foreign, kWrapperOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003291ACCESSORS(Script, type, Smi, kTypeOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003292ACCESSORS(Script, compilation_type, Smi, kCompilationTypeOffset)
sgjesse@chromium.org499aaa52009-11-30 08:07:20 +00003293ACCESSORS(Script, line_ends, Object, kLineEndsOffset)
sgjesse@chromium.org98180592009-12-02 08:17:28 +00003294ACCESSORS(Script, eval_from_shared, Object, kEvalFromSharedOffset)
ager@chromium.orge2902be2009-06-08 12:21:35 +00003295ACCESSORS(Script, eval_from_instructions_offset, Smi,
3296 kEvalFrominstructionsOffsetOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003297
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003298#ifdef ENABLE_DEBUGGER_SUPPORT
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003299ACCESSORS(DebugInfo, shared, SharedFunctionInfo, kSharedFunctionInfoIndex)
3300ACCESSORS(DebugInfo, original_code, Code, kOriginalCodeIndex)
3301ACCESSORS(DebugInfo, code, Code, kPatchedCodeIndex)
3302ACCESSORS(DebugInfo, break_points, FixedArray, kBreakPointsStateIndex)
3303
3304ACCESSORS(BreakPointInfo, code_position, Smi, kCodePositionIndex)
3305ACCESSORS(BreakPointInfo, source_position, Smi, kSourcePositionIndex)
3306ACCESSORS(BreakPointInfo, statement_position, Smi, kStatementPositionIndex)
3307ACCESSORS(BreakPointInfo, break_point_objects, Object, kBreakPointObjectsIndex)
ager@chromium.org65dad4b2009-04-23 08:48:43 +00003308#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003309
3310ACCESSORS(SharedFunctionInfo, name, Object, kNameOffset)
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003311ACCESSORS_GCSAFE(SharedFunctionInfo, construct_stub, Code, kConstructStubOffset)
3312ACCESSORS_GCSAFE(SharedFunctionInfo, initial_map, Object, kInitialMapOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003313ACCESSORS(SharedFunctionInfo, instance_class_name, Object,
3314 kInstanceClassNameOffset)
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003315ACCESSORS(SharedFunctionInfo, function_data, Object, kFunctionDataOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003316ACCESSORS(SharedFunctionInfo, script, Object, kScriptOffset)
3317ACCESSORS(SharedFunctionInfo, debug_info, Object, kDebugInfoOffset)
kasperl@chromium.orgd1e3e722009-04-14 13:38:25 +00003318ACCESSORS(SharedFunctionInfo, inferred_name, String, kInferredNameOffset)
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003319ACCESSORS(SharedFunctionInfo, this_property_assignments, Object,
3320 kThisPropertyAssignmentsOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003321
3322BOOL_ACCESSORS(FunctionTemplateInfo, flag, hidden_prototype,
3323 kHiddenPrototypeBit)
3324BOOL_ACCESSORS(FunctionTemplateInfo, flag, undetectable, kUndetectableBit)
3325BOOL_ACCESSORS(FunctionTemplateInfo, flag, needs_access_check,
3326 kNeedsAccessCheckBit)
3327BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_expression,
3328 kIsExpressionBit)
3329BOOL_ACCESSORS(SharedFunctionInfo, start_position_and_type, is_toplevel,
3330 kIsTopLevelBit)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003331BOOL_GETTER(SharedFunctionInfo,
3332 compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003333 has_only_simple_this_property_assignments,
3334 kHasOnlySimpleThisPropertyAssignments)
ager@chromium.orgc4c92722009-11-18 14:12:51 +00003335BOOL_ACCESSORS(SharedFunctionInfo,
3336 compiler_hints,
vegorov@chromium.org2356e6f2010-06-09 09:38:56 +00003337 allows_lazy_compilation,
3338 kAllowLazyCompilation)
whesse@chromium.org7b260152011-06-20 15:33:18 +00003339BOOL_ACCESSORS(SharedFunctionInfo,
3340 compiler_hints,
3341 uses_arguments,
3342 kUsesArguments)
3343BOOL_ACCESSORS(SharedFunctionInfo,
3344 compiler_hints,
3345 has_duplicate_parameters,
3346 kHasDuplicateParameters)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003347
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003348
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003349#if V8_HOST_ARCH_32_BIT
3350SMI_ACCESSORS(SharedFunctionInfo, length, kLengthOffset)
3351SMI_ACCESSORS(SharedFunctionInfo, formal_parameter_count,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003352 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003353SMI_ACCESSORS(SharedFunctionInfo, expected_nof_properties,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003354 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003355SMI_ACCESSORS(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3356SMI_ACCESSORS(SharedFunctionInfo, start_position_and_type,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003357 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003358SMI_ACCESSORS(SharedFunctionInfo, end_position, kEndPositionOffset)
3359SMI_ACCESSORS(SharedFunctionInfo, function_token_position,
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003360 kFunctionTokenPositionOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003361SMI_ACCESSORS(SharedFunctionInfo, compiler_hints,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003362 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003363SMI_ACCESSORS(SharedFunctionInfo, this_property_assignments_count,
sgjesse@chromium.org911335c2009-08-19 12:59:44 +00003364 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003365SMI_ACCESSORS(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003366#else
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003367
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003368#define PSEUDO_SMI_ACCESSORS_LO(holder, name, offset) \
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003369 STATIC_ASSERT(holder::offset % kPointerSize == 0); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003370 int holder::name() { \
3371 int value = READ_INT_FIELD(this, offset); \
3372 ASSERT(kHeapObjectTag == 1); \
3373 ASSERT((value & kHeapObjectTag) == 0); \
3374 return value >> 1; \
3375 } \
3376 void holder::set_##name(int value) { \
3377 ASSERT(kHeapObjectTag == 1); \
3378 ASSERT((value & 0xC0000000) == 0xC0000000 || \
3379 (value & 0xC0000000) == 0x000000000); \
3380 WRITE_INT_FIELD(this, \
3381 offset, \
3382 (value << 1) & ~kHeapObjectTag); \
3383 }
3384
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003385#define PSEUDO_SMI_ACCESSORS_HI(holder, name, offset) \
3386 STATIC_ASSERT(holder::offset % kPointerSize == kIntSize); \
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003387 INT_ACCESSORS(holder, name, offset)
3388
3389
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003390PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, length, kLengthOffset)
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003391PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3392 formal_parameter_count,
3393 kFormalParameterCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003394
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003395PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3396 expected_nof_properties,
3397 kExpectedNofPropertiesOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003398PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, num_literals, kNumLiteralsOffset)
3399
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003400PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo, end_position, kEndPositionOffset)
3401PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3402 start_position_and_type,
3403 kStartPositionAndTypeOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003404
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003405PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3406 function_token_position,
3407 kFunctionTokenPositionOffset)
3408PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo,
3409 compiler_hints,
3410 kCompilerHintsOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003411
whesse@chromium.orgf0ac72d2010-11-08 12:47:26 +00003412PSEUDO_SMI_ACCESSORS_LO(SharedFunctionInfo,
3413 this_property_assignments_count,
3414 kThisPropertyAssignmentsCountOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003415PSEUDO_SMI_ACCESSORS_HI(SharedFunctionInfo, opt_count, kOptCountOffset)
ricow@chromium.org30ce4112010-05-31 10:38:25 +00003416#endif
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003417
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003418
3419int SharedFunctionInfo::construction_count() {
3420 return READ_BYTE_FIELD(this, kConstructionCountOffset);
3421}
3422
3423
3424void SharedFunctionInfo::set_construction_count(int value) {
3425 ASSERT(0 <= value && value < 256);
3426 WRITE_BYTE_FIELD(this, kConstructionCountOffset, static_cast<byte>(value));
3427}
3428
3429
whesse@chromium.org7b260152011-06-20 15:33:18 +00003430BOOL_ACCESSORS(SharedFunctionInfo,
3431 compiler_hints,
3432 live_objects_may_exist,
3433 kLiveObjectsMayExist)
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003434
3435
3436bool SharedFunctionInfo::IsInobjectSlackTrackingInProgress() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003437 return initial_map() != HEAP->undefined_value();
whesse@chromium.org4a1fe7d2010-09-27 12:32:04 +00003438}
3439
3440
whesse@chromium.org7b260152011-06-20 15:33:18 +00003441BOOL_GETTER(SharedFunctionInfo,
3442 compiler_hints,
3443 optimization_disabled,
3444 kOptimizationDisabled)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003445
3446
3447void SharedFunctionInfo::set_optimization_disabled(bool disable) {
3448 set_compiler_hints(BooleanBit::set(compiler_hints(),
3449 kOptimizationDisabled,
3450 disable));
3451 // If disabling optimizations we reflect that in the code object so
3452 // it will not be counted as optimizable code.
3453 if ((code()->kind() == Code::FUNCTION) && disable) {
3454 code()->set_optimizable(false);
3455 }
3456}
3457
3458
whesse@chromium.org7b260152011-06-20 15:33:18 +00003459BOOL_ACCESSORS(SharedFunctionInfo,
3460 compiler_hints,
3461 strict_mode,
3462 kStrictModeFunction)
ricow@chromium.org83aa5492011-02-07 12:42:56 +00003463
3464
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00003465bool SharedFunctionInfo::native() {
3466 return BooleanBit::get(compiler_hints(), kNative);
ricow@chromium.org6fe7a8e2011-05-13 07:57:29 +00003467}
3468
3469
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00003470void SharedFunctionInfo::set_native(bool value) {
ricow@chromium.org6fe7a8e2011-05-13 07:57:29 +00003471 set_compiler_hints(BooleanBit::set(compiler_hints(),
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00003472 kNative,
ricow@chromium.org6fe7a8e2011-05-13 07:57:29 +00003473 value));
3474}
3475
3476
whesse@chromium.org7b260152011-06-20 15:33:18 +00003477bool SharedFunctionInfo::bound() {
3478 return BooleanBit::get(compiler_hints(), kBoundFunction);
3479}
3480
3481
3482void SharedFunctionInfo::set_bound(bool value) {
3483 set_compiler_hints(BooleanBit::set(compiler_hints(),
3484 kBoundFunction,
3485 value));
3486}
3487
3488
ager@chromium.orgce5e87b2010-03-10 10:24:18 +00003489ACCESSORS(CodeCache, default_cache, FixedArray, kDefaultCacheOffset)
3490ACCESSORS(CodeCache, normal_type_cache, Object, kNormalTypeCacheOffset)
3491
jkummerow@chromium.orge297f592011-06-08 10:05:15 +00003492ACCESSORS(PolymorphicCodeCache, cache, Object, kCacheOffset)
3493
sgjesse@chromium.org152a0b02009-10-07 13:50:16 +00003494bool Script::HasValidSource() {
3495 Object* src = this->source();
3496 if (!src->IsString()) return true;
3497 String* src_str = String::cast(src);
3498 if (!StringShape(src_str).IsExternal()) return true;
3499 if (src_str->IsAsciiRepresentation()) {
3500 return ExternalAsciiString::cast(src)->resource() != NULL;
3501 } else if (src_str->IsTwoByteRepresentation()) {
3502 return ExternalTwoByteString::cast(src)->resource() != NULL;
3503 }
3504 return true;
3505}
3506
3507
kasperl@chromium.orgb9123622008-09-17 14:05:56 +00003508void SharedFunctionInfo::DontAdaptArguments() {
3509 ASSERT(code()->kind() == Code::BUILTIN);
3510 set_formal_parameter_count(kDontAdaptArgumentsSentinel);
3511}
3512
3513
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003514int SharedFunctionInfo::start_position() {
3515 return start_position_and_type() >> kStartPositionShift;
3516}
3517
3518
3519void SharedFunctionInfo::set_start_position(int start_position) {
3520 set_start_position_and_type((start_position << kStartPositionShift)
3521 | (start_position_and_type() & ~kStartPositionMask));
3522}
3523
3524
3525Code* SharedFunctionInfo::code() {
3526 return Code::cast(READ_FIELD(this, kCodeOffset));
3527}
3528
3529
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003530Code* SharedFunctionInfo::unchecked_code() {
3531 return reinterpret_cast<Code*>(READ_FIELD(this, kCodeOffset));
3532}
3533
3534
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00003535void SharedFunctionInfo::set_code(Code* value, WriteBarrierMode mode) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003536 WRITE_FIELD(this, kCodeOffset, value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003537 ASSERT(!Isolate::Current()->heap()->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003538}
3539
3540
ager@chromium.orgb5737492010-07-15 09:29:43 +00003541SerializedScopeInfo* SharedFunctionInfo::scope_info() {
3542 return reinterpret_cast<SerializedScopeInfo*>(
3543 READ_FIELD(this, kScopeInfoOffset));
3544}
3545
3546
3547void SharedFunctionInfo::set_scope_info(SerializedScopeInfo* value,
3548 WriteBarrierMode mode) {
3549 WRITE_FIELD(this, kScopeInfoOffset, reinterpret_cast<Object*>(value));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003550 CONDITIONAL_WRITE_BARRIER(GetHeap(), this, kScopeInfoOffset, mode);
ager@chromium.orgb5737492010-07-15 09:29:43 +00003551}
3552
3553
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003554Smi* SharedFunctionInfo::deopt_counter() {
3555 return reinterpret_cast<Smi*>(READ_FIELD(this, kDeoptCounterOffset));
3556}
3557
3558
3559void SharedFunctionInfo::set_deopt_counter(Smi* value) {
3560 WRITE_FIELD(this, kDeoptCounterOffset, value);
3561}
3562
3563
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003564bool SharedFunctionInfo::is_compiled() {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003565 return code() !=
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003566 Isolate::Current()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003567}
3568
3569
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003570bool SharedFunctionInfo::IsApiFunction() {
3571 return function_data()->IsFunctionTemplateInfo();
3572}
3573
3574
3575FunctionTemplateInfo* SharedFunctionInfo::get_api_func_data() {
3576 ASSERT(IsApiFunction());
3577 return FunctionTemplateInfo::cast(function_data());
3578}
3579
3580
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003581bool SharedFunctionInfo::HasBuiltinFunctionId() {
sgjesse@chromium.org720dc0b2010-05-10 09:25:39 +00003582 return function_data()->IsSmi();
3583}
3584
3585
ager@chromium.org5f0c45f2010-12-17 08:51:21 +00003586BuiltinFunctionId SharedFunctionInfo::builtin_function_id() {
3587 ASSERT(HasBuiltinFunctionId());
3588 return static_cast<BuiltinFunctionId>(Smi::cast(function_data())->value());
vegorov@chromium.orgf8372902010-03-15 10:26:20 +00003589}
3590
3591
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003592int SharedFunctionInfo::code_age() {
3593 return (compiler_hints() >> kCodeAgeShift) & kCodeAgeMask;
3594}
3595
3596
3597void SharedFunctionInfo::set_code_age(int code_age) {
3598 set_compiler_hints(compiler_hints() |
3599 ((code_age & kCodeAgeMask) << kCodeAgeShift));
3600}
3601
3602
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003603bool SharedFunctionInfo::has_deoptimization_support() {
3604 Code* code = this->code();
3605 return code->kind() == Code::FUNCTION && code->has_deoptimization_support();
3606}
3607
3608
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003609bool JSFunction::IsBuiltin() {
3610 return context()->global()->IsJSBuiltinsObject();
3611}
3612
3613
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003614bool JSFunction::NeedsArgumentsAdaption() {
3615 return shared()->formal_parameter_count() !=
3616 SharedFunctionInfo::kDontAdaptArgumentsSentinel;
3617}
3618
3619
3620bool JSFunction::IsOptimized() {
3621 return code()->kind() == Code::OPTIMIZED_FUNCTION;
3622}
3623
3624
ager@chromium.orga9aa5fa2011-04-13 08:46:07 +00003625bool JSFunction::IsOptimizable() {
3626 return code()->kind() == Code::FUNCTION && code()->optimizable();
3627}
3628
3629
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003630bool JSFunction::IsMarkedForLazyRecompilation() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003631 return code() == GetIsolate()->builtins()->builtin(Builtins::kLazyRecompile);
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003632}
3633
3634
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003635Code* JSFunction::code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003636 return Code::cast(unchecked_code());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003637}
3638
3639
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003640Code* JSFunction::unchecked_code() {
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003641 return reinterpret_cast<Code*>(
3642 Code::GetObjectFromEntryAddress(FIELD_ADDR(this, kCodeEntryOffset)));
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003643}
3644
3645
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003646void JSFunction::set_code(Code* value) {
vegorov@chromium.org26c16f82010-08-11 13:41:03 +00003647 // Skip the write barrier because code is never in new space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003648 ASSERT(!HEAP->InNewSpace(value));
erik.corry@gmail.com145eff52010-08-23 11:36:18 +00003649 Address entry = value->entry();
3650 WRITE_INTPTR_FIELD(this, kCodeEntryOffset, reinterpret_cast<intptr_t>(entry));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003651}
3652
3653
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003654void JSFunction::ReplaceCode(Code* code) {
3655 bool was_optimized = IsOptimized();
3656 bool is_optimized = code->kind() == Code::OPTIMIZED_FUNCTION;
3657
3658 set_code(code);
3659
3660 // Add/remove the function from the list of optimized functions for this
3661 // context based on the state change.
3662 if (!was_optimized && is_optimized) {
3663 context()->global_context()->AddOptimizedFunction(this);
3664 }
3665 if (was_optimized && !is_optimized) {
3666 context()->global_context()->RemoveOptimizedFunction(this);
3667 }
3668}
3669
3670
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003671Context* JSFunction::context() {
3672 return Context::cast(READ_FIELD(this, kContextOffset));
3673}
3674
3675
3676Object* JSFunction::unchecked_context() {
3677 return READ_FIELD(this, kContextOffset);
3678}
3679
3680
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00003681SharedFunctionInfo* JSFunction::unchecked_shared() {
3682 return reinterpret_cast<SharedFunctionInfo*>(
3683 READ_FIELD(this, kSharedFunctionInfoOffset));
3684}
3685
3686
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003687void JSFunction::set_context(Object* value) {
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003688 ASSERT(value->IsUndefined() || value->IsContext());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003689 WRITE_FIELD(this, kContextOffset, value);
3690 WRITE_BARRIER(this, kContextOffset);
3691}
3692
3693ACCESSORS(JSFunction, prototype_or_initial_map, Object,
3694 kPrototypeOrInitialMapOffset)
3695
3696
3697Map* JSFunction::initial_map() {
3698 return Map::cast(prototype_or_initial_map());
3699}
3700
3701
3702void JSFunction::set_initial_map(Map* value) {
3703 set_prototype_or_initial_map(value);
3704}
3705
3706
3707bool JSFunction::has_initial_map() {
3708 return prototype_or_initial_map()->IsMap();
3709}
3710
3711
3712bool JSFunction::has_instance_prototype() {
3713 return has_initial_map() || !prototype_or_initial_map()->IsTheHole();
3714}
3715
3716
3717bool JSFunction::has_prototype() {
3718 return map()->has_non_instance_prototype() || has_instance_prototype();
3719}
3720
3721
3722Object* JSFunction::instance_prototype() {
3723 ASSERT(has_instance_prototype());
3724 if (has_initial_map()) return initial_map()->prototype();
3725 // When there is no initial map and the prototype is a JSObject, the
3726 // initial map field is used for the prototype field.
3727 return prototype_or_initial_map();
3728}
3729
3730
3731Object* JSFunction::prototype() {
3732 ASSERT(has_prototype());
3733 // If the function's prototype property has been set to a non-JSObject
3734 // value, that value is stored in the constructor field of the map.
3735 if (map()->has_non_instance_prototype()) return map()->constructor();
3736 return instance_prototype();
3737}
3738
kmillikin@chromium.org4111b802010-05-03 10:34:42 +00003739bool JSFunction::should_have_prototype() {
3740 return map()->function_with_prototype();
3741}
3742
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003743
3744bool JSFunction::is_compiled() {
fschneider@chromium.org7979bbb2011-03-28 10:47:03 +00003745 return code() != GetIsolate()->builtins()->builtin(Builtins::kLazyCompile);
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003746}
3747
3748
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003749int JSFunction::NumberOfLiterals() {
3750 return literals()->length();
3751}
3752
3753
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003754Object* JSBuiltinsObject::javascript_builtin(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003755 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003756 return READ_FIELD(this, OffsetOfFunctionWithId(id));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003757}
3758
3759
3760void JSBuiltinsObject::set_javascript_builtin(Builtins::JavaScript id,
3761 Object* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003762 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003763 WRITE_FIELD(this, OffsetOfFunctionWithId(id), value);
3764 WRITE_BARRIER(this, OffsetOfFunctionWithId(id));
3765}
3766
3767
3768Code* JSBuiltinsObject::javascript_builtin_code(Builtins::JavaScript id) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003769 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003770 return Code::cast(READ_FIELD(this, OffsetOfCodeWithId(id)));
3771}
3772
3773
3774void JSBuiltinsObject::set_javascript_builtin_code(Builtins::JavaScript id,
3775 Code* value) {
sgjesse@chromium.orgc6c57182011-01-17 12:24:25 +00003776 ASSERT(id < kJSBuiltinsCount); // id is unsigned.
ricow@chromium.orgc9c80822010-04-21 08:22:37 +00003777 WRITE_FIELD(this, OffsetOfCodeWithId(id), value);
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00003778 ASSERT(!HEAP->InNewSpace(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003779}
3780
3781
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003782ACCESSORS(JSProxy, handler, Object, kHandlerOffset)
rossberg@chromium.org717967f2011-07-20 13:44:42 +00003783ACCESSORS(JSProxy, padding, Object, kPaddingOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003784
3785
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003786Address Foreign::address() {
3787 return AddressFrom<Address>(READ_INTPTR_FIELD(this, kAddressOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003788}
3789
3790
ager@chromium.orgea91cc52011-05-23 06:06:11 +00003791void Foreign::set_address(Address value) {
3792 WRITE_INTPTR_FIELD(this, kAddressOffset, OffsetFrom(value));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003793}
3794
3795
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003796ACCESSORS(JSValue, value, Object, kValueOffset)
3797
3798
3799JSValue* JSValue::cast(Object* obj) {
3800 ASSERT(obj->IsJSValue());
3801 ASSERT(HeapObject::cast(obj)->Size() == JSValue::kSize);
3802 return reinterpret_cast<JSValue*>(obj);
3803}
3804
3805
kmillikin@chromium.org31b12772011-02-02 16:08:26 +00003806ACCESSORS(JSMessageObject, type, String, kTypeOffset)
3807ACCESSORS(JSMessageObject, arguments, JSArray, kArgumentsOffset)
3808ACCESSORS(JSMessageObject, script, Object, kScriptOffset)
3809ACCESSORS(JSMessageObject, stack_trace, Object, kStackTraceOffset)
3810ACCESSORS(JSMessageObject, stack_frames, Object, kStackFramesOffset)
3811SMI_ACCESSORS(JSMessageObject, start_position, kStartPositionOffset)
3812SMI_ACCESSORS(JSMessageObject, end_position, kEndPositionOffset)
3813
3814
3815JSMessageObject* JSMessageObject::cast(Object* obj) {
3816 ASSERT(obj->IsJSMessageObject());
3817 ASSERT(HeapObject::cast(obj)->Size() == JSMessageObject::kSize);
3818 return reinterpret_cast<JSMessageObject*>(obj);
3819}
3820
3821
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003822INT_ACCESSORS(Code, instruction_size, kInstructionSizeOffset)
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003823ACCESSORS(Code, relocation_info, ByteArray, kRelocationInfoOffset)
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003824ACCESSORS(Code, deoptimization_data, FixedArray, kDeoptimizationDataOffset)
vegorov@chromium.org7304bca2011-05-16 12:14:13 +00003825ACCESSORS(Code, next_code_flushing_candidate,
3826 Object, kNextCodeFlushingCandidateOffset)
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003827
3828
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003829byte* Code::instruction_start() {
3830 return FIELD_ADDR(this, kHeaderSize);
3831}
3832
3833
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003834byte* Code::instruction_end() {
3835 return instruction_start() + instruction_size();
3836}
3837
3838
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003839int Code::body_size() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003840 return RoundUp(instruction_size(), kObjectAlignment);
3841}
3842
3843
kasperl@chromium.orga5551262010-12-07 12:49:48 +00003844FixedArray* Code::unchecked_deoptimization_data() {
3845 return reinterpret_cast<FixedArray*>(
3846 READ_FIELD(this, kDeoptimizationDataOffset));
3847}
3848
3849
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003850ByteArray* Code::unchecked_relocation_info() {
3851 return reinterpret_cast<ByteArray*>(READ_FIELD(this, kRelocationInfoOffset));
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003852}
3853
3854
3855byte* Code::relocation_start() {
erik.corry@gmail.com4a2e25e2010-07-07 12:22:46 +00003856 return unchecked_relocation_info()->GetDataStartAddress();
3857}
3858
3859
3860int Code::relocation_size() {
3861 return unchecked_relocation_info()->length();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003862}
3863
3864
3865byte* Code::entry() {
3866 return instruction_start();
3867}
3868
3869
3870bool Code::contains(byte* pc) {
3871 return (instruction_start() <= pc) &&
ricow@chromium.org65fae842010-08-25 15:26:24 +00003872 (pc <= instruction_start() + instruction_size());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003873}
3874
3875
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003876ACCESSORS(JSArray, length, Object, kLengthOffset)
3877
3878
ager@chromium.org236ad962008-09-25 09:45:57 +00003879ACCESSORS(JSRegExp, data, Object, kDataOffset)
ager@chromium.org236ad962008-09-25 09:45:57 +00003880
3881
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003882JSRegExp::Type JSRegExp::TypeTag() {
3883 Object* data = this->data();
3884 if (data->IsUndefined()) return JSRegExp::NOT_COMPILED;
3885 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kTagIndex));
3886 return static_cast<JSRegExp::Type>(smi->value());
ager@chromium.org236ad962008-09-25 09:45:57 +00003887}
3888
3889
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003890JSRegExp::Type JSRegExp::TypeTagUnchecked() {
3891 Smi* smi = Smi::cast(DataAtUnchecked(kTagIndex));
3892 return static_cast<JSRegExp::Type>(smi->value());
3893}
3894
3895
ager@chromium.orgbb29dc92009-03-24 13:25:23 +00003896int JSRegExp::CaptureCount() {
3897 switch (TypeTag()) {
3898 case ATOM:
3899 return 0;
3900 case IRREGEXP:
3901 return Smi::cast(DataAt(kIrregexpCaptureCountIndex))->value();
3902 default:
3903 UNREACHABLE();
3904 return -1;
3905 }
3906}
3907
3908
ager@chromium.orga74f0da2008-12-03 16:05:52 +00003909JSRegExp::Flags JSRegExp::GetFlags() {
3910 ASSERT(this->data()->IsFixedArray());
3911 Object* data = this->data();
3912 Smi* smi = Smi::cast(FixedArray::cast(data)->get(kFlagsIndex));
3913 return Flags(smi->value());
3914}
3915
3916
3917String* JSRegExp::Pattern() {
3918 ASSERT(this->data()->IsFixedArray());
3919 Object* data = this->data();
3920 String* pattern= String::cast(FixedArray::cast(data)->get(kSourceIndex));
3921 return pattern;
3922}
3923
3924
kasperl@chromium.org9fe21c62008-10-28 08:53:51 +00003925Object* JSRegExp::DataAt(int index) {
3926 ASSERT(TypeTag() != NOT_COMPILED);
3927 return FixedArray::cast(data())->get(index);
ager@chromium.org236ad962008-09-25 09:45:57 +00003928}
3929
3930
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003931Object* JSRegExp::DataAtUnchecked(int index) {
3932 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
3933 int offset = FixedArray::kHeaderSize + index * kPointerSize;
3934 return READ_FIELD(fa, offset);
3935}
3936
3937
kasperl@chromium.org7be3c992009-03-12 07:19:55 +00003938void JSRegExp::SetDataAt(int index, Object* value) {
3939 ASSERT(TypeTag() != NOT_COMPILED);
3940 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
3941 FixedArray::cast(data())->set(index, value);
3942}
3943
3944
jkummerow@chromium.orgddda9e82011-07-06 11:27:02 +00003945void JSRegExp::SetDataAtUnchecked(int index, Object* value, Heap* heap) {
3946 ASSERT(index >= kDataIndex); // Only implementation data can be set this way.
3947 FixedArray* fa = reinterpret_cast<FixedArray*>(data());
3948 if (value->IsSmi()) {
3949 fa->set_unchecked(index, Smi::cast(value));
3950 } else {
3951 fa->set_unchecked(heap, index, value, SKIP_WRITE_BARRIER);
3952 }
3953}
3954
3955
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003956JSObject::ElementsKind JSObject::GetElementsKind() {
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003957 ElementsKind kind = map()->elements_kind();
3958 ASSERT((kind == FAST_ELEMENTS &&
3959 (elements()->map() == GetHeap()->fixed_array_map() ||
3960 elements()->map() == GetHeap()->fixed_cow_array_map())) ||
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003961 (kind == FAST_DOUBLE_ELEMENTS &&
3962 elements()->IsFixedDoubleArray()) ||
erik.corry@gmail.comd6076d92011-06-06 09:39:18 +00003963 (kind == DICTIONARY_ELEMENTS &&
3964 elements()->IsFixedArray() &&
3965 elements()->IsDictionary()) ||
3966 (kind > DICTIONARY_ELEMENTS));
3967 return kind;
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003968}
3969
3970
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00003971bool JSObject::HasFastElements() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003972 return GetElementsKind() == FAST_ELEMENTS;
3973}
3974
3975
svenpanne@chromium.org6d786c92011-06-15 10:58:27 +00003976bool JSObject::HasFastDoubleElements() {
3977 return GetElementsKind() == FAST_DOUBLE_ELEMENTS;
3978}
3979
3980
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00003981bool JSObject::HasDictionaryElements() {
3982 return GetElementsKind() == DICTIONARY_ELEMENTS;
3983}
3984
3985
ager@chromium.org3811b432009-10-28 14:53:37 +00003986bool JSObject::HasExternalArrayElements() {
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003987 HeapObject* array = elements();
3988 ASSERT(array != NULL);
3989 return array->IsExternalArray();
ager@chromium.org3811b432009-10-28 14:53:37 +00003990}
3991
3992
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00003993#define EXTERNAL_ELEMENTS_CHECK(name, type) \
3994bool JSObject::HasExternal##name##Elements() { \
3995 HeapObject* array = elements(); \
3996 ASSERT(array != NULL); \
3997 if (!array->IsHeapObject()) \
3998 return false; \
3999 return array->map()->instance_type() == type; \
ager@chromium.org3811b432009-10-28 14:53:37 +00004000}
4001
4002
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004003EXTERNAL_ELEMENTS_CHECK(Byte, EXTERNAL_BYTE_ARRAY_TYPE)
4004EXTERNAL_ELEMENTS_CHECK(UnsignedByte, EXTERNAL_UNSIGNED_BYTE_ARRAY_TYPE)
4005EXTERNAL_ELEMENTS_CHECK(Short, EXTERNAL_SHORT_ARRAY_TYPE)
4006EXTERNAL_ELEMENTS_CHECK(UnsignedShort,
4007 EXTERNAL_UNSIGNED_SHORT_ARRAY_TYPE)
4008EXTERNAL_ELEMENTS_CHECK(Int, EXTERNAL_INT_ARRAY_TYPE)
4009EXTERNAL_ELEMENTS_CHECK(UnsignedInt,
4010 EXTERNAL_UNSIGNED_INT_ARRAY_TYPE)
4011EXTERNAL_ELEMENTS_CHECK(Float,
4012 EXTERNAL_FLOAT_ARRAY_TYPE)
erik.corry@gmail.com3847bd52011-04-27 10:38:56 +00004013EXTERNAL_ELEMENTS_CHECK(Double,
4014 EXTERNAL_DOUBLE_ARRAY_TYPE)
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004015EXTERNAL_ELEMENTS_CHECK(Pixel, EXTERNAL_PIXEL_ARRAY_TYPE)
ager@chromium.org3811b432009-10-28 14:53:37 +00004016
4017
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004018bool JSObject::HasNamedInterceptor() {
4019 return map()->has_named_interceptor();
4020}
4021
4022
4023bool JSObject::HasIndexedInterceptor() {
4024 return map()->has_indexed_interceptor();
4025}
4026
4027
ager@chromium.org5c838252010-02-19 08:53:10 +00004028bool JSObject::AllowsSetElementsLength() {
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004029 bool result = elements()->IsFixedArray() ||
4030 elements()->IsFixedDoubleArray();
danno@chromium.org4d3fe4e2011-03-10 10:14:28 +00004031 ASSERT(result == !HasExternalArrayElements());
ager@chromium.org5c838252010-02-19 08:53:10 +00004032 return result;
4033}
4034
4035
lrn@chromium.org303ada72010-10-27 09:33:13 +00004036MaybeObject* JSObject::EnsureWritableFastElements() {
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004037 ASSERT(HasFastElements());
4038 FixedArray* elems = FixedArray::cast(elements());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004039 Isolate* isolate = GetIsolate();
4040 if (elems->map() != isolate->heap()->fixed_cow_array_map()) return elems;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004041 Object* writable_elems;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004042 { MaybeObject* maybe_writable_elems = isolate->heap()->CopyFixedArrayWithMap(
4043 elems, isolate->heap()->fixed_array_map());
lrn@chromium.org303ada72010-10-27 09:33:13 +00004044 if (!maybe_writable_elems->ToObject(&writable_elems)) {
4045 return maybe_writable_elems;
4046 }
4047 }
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004048 set_elements(FixedArray::cast(writable_elems));
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004049 isolate->counters()->cow_arrays_converted()->Increment();
ricow@chromium.org0b9f8502010-08-18 07:45:01 +00004050 return writable_elems;
4051}
4052
4053
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004054StringDictionary* JSObject::property_dictionary() {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004055 ASSERT(!HasFastProperties());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004056 return StringDictionary::cast(properties());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004057}
4058
4059
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004060NumberDictionary* JSObject::element_dictionary() {
sgjesse@chromium.org0b6db592009-07-30 14:48:31 +00004061 ASSERT(HasDictionaryElements());
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004062 return NumberDictionary::cast(elements());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004063}
4064
4065
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004066bool String::IsHashFieldComputed(uint32_t field) {
4067 return (field & kHashNotComputedMask) == 0;
4068}
4069
4070
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004071bool String::HasHashCode() {
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004072 return IsHashFieldComputed(hash_field());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004073}
4074
4075
4076uint32_t String::Hash() {
4077 // Fast case: has hash code already been computed?
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004078 uint32_t field = hash_field();
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004079 if (IsHashFieldComputed(field)) return field >> kHashShift;
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004080 // Slow case: compute hash code and set it.
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004081 return ComputeAndSetHash();
4082}
4083
4084
ager@chromium.org7c537e22008-10-16 08:43:32 +00004085StringHasher::StringHasher(int length)
4086 : length_(length),
4087 raw_running_hash_(0),
4088 array_index_(0),
4089 is_array_index_(0 < length_ && length_ <= String::kMaxArrayIndexSize),
4090 is_first_char_(true),
4091 is_valid_(true) { }
4092
4093
4094bool StringHasher::has_trivial_hash() {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004095 return length_ > String::kMaxHashCalcLength;
ager@chromium.org7c537e22008-10-16 08:43:32 +00004096}
4097
4098
4099void StringHasher::AddCharacter(uc32 c) {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004100 // Use the Jenkins one-at-a-time hash function to update the hash
4101 // for the given character.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004102 raw_running_hash_ += c;
4103 raw_running_hash_ += (raw_running_hash_ << 10);
4104 raw_running_hash_ ^= (raw_running_hash_ >> 6);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004105 // Incremental array index computation.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004106 if (is_array_index_) {
4107 if (c < '0' || c > '9') {
4108 is_array_index_ = false;
4109 } else {
4110 int d = c - '0';
4111 if (is_first_char_) {
4112 is_first_char_ = false;
4113 if (c == '0' && length_ > 1) {
4114 is_array_index_ = false;
4115 return;
4116 }
4117 }
4118 if (array_index_ > 429496729U - ((d + 2) >> 3)) {
4119 is_array_index_ = false;
4120 } else {
4121 array_index_ = array_index_ * 10 + d;
4122 }
4123 }
4124 }
4125}
4126
4127
4128void StringHasher::AddCharacterNoIndex(uc32 c) {
4129 ASSERT(!is_array_index());
4130 raw_running_hash_ += c;
4131 raw_running_hash_ += (raw_running_hash_ << 10);
4132 raw_running_hash_ ^= (raw_running_hash_ >> 6);
4133}
4134
4135
4136uint32_t StringHasher::GetHash() {
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004137 // Get the calculated raw hash value and do some more bit ops to distribute
4138 // the hash further. Ensure that we never return zero as the hash value.
ager@chromium.org7c537e22008-10-16 08:43:32 +00004139 uint32_t result = raw_running_hash_;
4140 result += (result << 3);
4141 result ^= (result >> 11);
4142 result += (result << 15);
ager@chromium.org3b45ab52009-03-19 22:21:34 +00004143 if (result == 0) {
4144 result = 27;
4145 }
ager@chromium.org7c537e22008-10-16 08:43:32 +00004146 return result;
4147}
4148
4149
whesse@chromium.orgb08986c2011-03-14 16:13:42 +00004150template <typename schar>
4151uint32_t HashSequentialString(const schar* chars, int length) {
4152 StringHasher hasher(length);
4153 if (!hasher.has_trivial_hash()) {
4154 int i;
4155 for (i = 0; hasher.is_array_index() && (i < length); i++) {
4156 hasher.AddCharacter(chars[i]);
4157 }
4158 for (; i < length; i++) {
4159 hasher.AddCharacterNoIndex(chars[i]);
4160 }
4161 }
4162 return hasher.GetHashField();
4163}
4164
4165
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004166bool String::AsArrayIndex(uint32_t* index) {
sgjesse@chromium.orgac6aa172009-12-04 12:29:05 +00004167 uint32_t field = hash_field();
lrn@chromium.org1af7e1b2010-06-07 11:12:01 +00004168 if (IsHashFieldComputed(field) && (field & kIsNotArrayIndexMask)) {
4169 return false;
4170 }
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004171 return SlowAsArrayIndex(index);
4172}
4173
4174
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004175Object* JSReceiver::GetPrototype() {
4176 return HeapObject::cast(this)->map()->prototype();
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004177}
4178
4179
rossberg@chromium.org717967f2011-07-20 13:44:42 +00004180bool JSReceiver::HasProperty(String* name) {
4181 if (IsJSProxy()) {
4182 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4183 }
4184 return GetPropertyAttribute(name) != ABSENT;
4185}
4186
4187
4188bool JSReceiver::HasLocalProperty(String* name) {
4189 if (IsJSProxy()) {
4190 return JSProxy::cast(this)->HasPropertyWithHandler(name);
4191 }
4192 return GetLocalPropertyAttribute(name) != ABSENT;
4193}
4194
4195
ricow@chromium.orgd2be9012011-06-01 06:00:58 +00004196PropertyAttributes JSReceiver::GetPropertyAttribute(String* key) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004197 return GetPropertyAttributeWithReceiver(this, key);
4198}
4199
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004200// TODO(504): this may be useful in other places too where JSGlobalProxy
4201// is used.
4202Object* JSObject::BypassGlobalProxy() {
4203 if (IsJSGlobalProxy()) {
4204 Object* proto = GetPrototype();
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004205 if (proto->IsNull()) return GetHeap()->undefined_value();
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004206 ASSERT(proto->IsJSGlobalObject());
4207 return proto;
4208 }
4209 return this;
4210}
4211
4212
4213bool JSObject::HasHiddenPropertiesObject() {
4214 ASSERT(!IsJSGlobalProxy());
4215 return GetPropertyAttributePostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004216 GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004217 false) != ABSENT;
4218}
4219
4220
4221Object* JSObject::GetHiddenPropertiesObject() {
4222 ASSERT(!IsJSGlobalProxy());
4223 PropertyAttributes attributes;
lrn@chromium.org303ada72010-10-27 09:33:13 +00004224 // You can't install a getter on a property indexed by the hidden symbol,
4225 // so we can be sure that GetLocalPropertyPostInterceptor returns a real
4226 // object.
4227 Object* result =
4228 GetLocalPropertyPostInterceptor(this,
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004229 GetHeap()->hidden_symbol(),
lrn@chromium.org303ada72010-10-27 09:33:13 +00004230 &attributes)->ToObjectUnchecked();
4231 return result;
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004232}
4233
4234
lrn@chromium.org303ada72010-10-27 09:33:13 +00004235MaybeObject* JSObject::SetHiddenPropertiesObject(Object* hidden_obj) {
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004236 ASSERT(!IsJSGlobalProxy());
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004237 return SetPropertyPostInterceptor(GetHeap()->hidden_symbol(),
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004238 hidden_obj,
ager@chromium.org9ee27ae2011-03-02 13:43:26 +00004239 DONT_ENUM,
4240 kNonStrictMode);
ager@chromium.orgc4c92722009-11-18 14:12:51 +00004241}
4242
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004243
4244bool JSObject::HasElement(uint32_t index) {
4245 return HasElementWithReceiver(this, index);
4246}
4247
4248
4249bool AccessorInfo::all_can_read() {
4250 return BooleanBit::get(flag(), kAllCanReadBit);
4251}
4252
4253
4254void AccessorInfo::set_all_can_read(bool value) {
4255 set_flag(BooleanBit::set(flag(), kAllCanReadBit, value));
4256}
4257
4258
4259bool AccessorInfo::all_can_write() {
4260 return BooleanBit::get(flag(), kAllCanWriteBit);
4261}
4262
4263
4264void AccessorInfo::set_all_can_write(bool value) {
4265 set_flag(BooleanBit::set(flag(), kAllCanWriteBit, value));
4266}
4267
4268
ager@chromium.org870a0b62008-11-04 11:43:05 +00004269bool AccessorInfo::prohibits_overwriting() {
4270 return BooleanBit::get(flag(), kProhibitsOverwritingBit);
4271}
4272
4273
4274void AccessorInfo::set_prohibits_overwriting(bool value) {
4275 set_flag(BooleanBit::set(flag(), kProhibitsOverwritingBit, value));
4276}
4277
4278
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004279PropertyAttributes AccessorInfo::property_attributes() {
4280 return AttributesField::decode(static_cast<uint32_t>(flag()->value()));
4281}
4282
4283
4284void AccessorInfo::set_property_attributes(PropertyAttributes attributes) {
4285 ASSERT(AttributesField::is_valid(attributes));
4286 int rest_value = flag()->value() & ~AttributesField::mask();
4287 set_flag(Smi::FromInt(rest_value | AttributesField::encode(attributes)));
4288}
4289
karlklose@chromium.org44bc7082011-04-11 12:33:05 +00004290
4291template<typename Shape, typename Key>
4292void Dictionary<Shape, Key>::SetEntry(int entry,
4293 Object* key,
4294 Object* value) {
4295 SetEntry(entry, key, value, PropertyDetails(Smi::FromInt(0)));
4296}
4297
4298
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004299template<typename Shape, typename Key>
4300void Dictionary<Shape, Key>::SetEntry(int entry,
4301 Object* key,
4302 Object* value,
4303 PropertyDetails details) {
kasperl@chromium.orgdefbd102009-07-13 14:04:26 +00004304 ASSERT(!key->IsString() || details.IsDeleted() || details.index() > 0);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004305 int index = HashTable<Shape, Key>::EntryToIndex(entry);
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004306 AssertNoAllocation no_gc;
4307 WriteBarrierMode mode = FixedArray::GetWriteBarrierMode(no_gc);
kasperl@chromium.org86f77b72009-07-06 08:21:57 +00004308 FixedArray::set(index, key, mode);
4309 FixedArray::set(index+1, value, mode);
4310 FixedArray::fast_set(this, index+2, details.AsSmi());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004311}
4312
4313
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004314bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) {
4315 ASSERT(other->IsNumber());
4316 return key == static_cast<uint32_t>(other->Number());
4317}
4318
4319
4320uint32_t NumberDictionaryShape::Hash(uint32_t key) {
4321 return ComputeIntegerHash(key);
4322}
4323
4324
4325uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) {
4326 ASSERT(other->IsNumber());
4327 return ComputeIntegerHash(static_cast<uint32_t>(other->Number()));
4328}
4329
4330
4331MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) {
4332 return Isolate::Current()->heap()->NumberFromUint32(key);
4333}
4334
4335
4336bool StringDictionaryShape::IsMatch(String* key, Object* other) {
4337 // We know that all entries in a hash table had their hash keys created.
4338 // Use that knowledge to have fast failure.
4339 if (key->Hash() != String::cast(other)->Hash()) return false;
4340 return key->Equals(String::cast(other));
4341}
4342
4343
4344uint32_t StringDictionaryShape::Hash(String* key) {
4345 return key->Hash();
4346}
4347
4348
4349uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) {
4350 return String::cast(other)->Hash();
4351}
4352
4353
4354MaybeObject* StringDictionaryShape::AsObject(String* key) {
4355 return key;
4356}
4357
4358
4359void Map::ClearCodeCache(Heap* heap) {
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004360 // No write barrier is needed since empty_fixed_array is not in new space.
4361 // Please note this function is used during marking:
4362 // - MarkCompactCollector::MarkUnmarkedObject
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004363 ASSERT(!heap->InNewSpace(heap->raw_unchecked_empty_fixed_array()));
4364 WRITE_FIELD(this, kCodeCacheOffset, heap->raw_unchecked_empty_fixed_array());
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004365}
4366
4367
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004368void JSArray::EnsureSize(int required_size) {
4369 ASSERT(HasFastElements());
ricow@chromium.org30ce4112010-05-31 10:38:25 +00004370 FixedArray* elts = FixedArray::cast(elements());
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004371 const int kArraySizeThatFitsComfortablyInNewSpace = 128;
4372 if (elts->length() < required_size) {
4373 // Doubling in size would be overkill, but leave some slack to avoid
4374 // constantly growing.
4375 Expand(required_size + (required_size >> 3));
4376 // It's a performance benefit to keep a frequently used array in new-space.
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004377 } else if (!GetHeap()->new_space()->Contains(elts) &&
ager@chromium.org6141cbe2009-11-20 12:14:52 +00004378 required_size < kArraySizeThatFitsComfortablyInNewSpace) {
4379 // Expand will allocate a new backing store in new space even if the size
4380 // we asked for isn't larger than what we had before.
4381 Expand(required_size);
4382 }
ager@chromium.org5aa501c2009-06-23 07:57:28 +00004383}
4384
4385
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004386void JSArray::set_length(Smi* length) {
4387 set_length(static_cast<Object*>(length), SKIP_WRITE_BARRIER);
4388}
4389
4390
ager@chromium.org7c537e22008-10-16 08:43:32 +00004391void JSArray::SetContent(FixedArray* storage) {
sgjesse@chromium.orgb302e562010-02-03 11:26:59 +00004392 set_length(Smi::FromInt(storage->length()));
ager@chromium.org7c537e22008-10-16 08:43:32 +00004393 set_elements(storage);
4394}
4395
4396
lrn@chromium.org303ada72010-10-27 09:33:13 +00004397MaybeObject* FixedArray::Copy() {
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004398 if (length() == 0) return this;
sgjesse@chromium.orgea88ce92011-03-23 11:19:56 +00004399 return GetHeap()->CopyFixedArray(this);
4400}
4401
4402
4403Relocatable::Relocatable(Isolate* isolate) {
4404 ASSERT(isolate == Isolate::Current());
4405 isolate_ = isolate;
4406 prev_ = isolate->relocatable_top();
4407 isolate->set_relocatable_top(this);
4408}
4409
4410
4411Relocatable::~Relocatable() {
4412 ASSERT(isolate_ == Isolate::Current());
4413 ASSERT_EQ(isolate_->relocatable_top(), this);
4414 isolate_->set_relocatable_top(prev_);
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004415}
4416
4417
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004418int JSObject::BodyDescriptor::SizeOf(Map* map, HeapObject* object) {
4419 return map->instance_size();
4420}
4421
4422
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004423void Foreign::ForeignIterateBody(ObjectVisitor* v) {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004424 v->VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004425 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004426}
4427
4428
4429template<typename StaticVisitor>
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004430void Foreign::ForeignIterateBody() {
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004431 StaticVisitor::VisitExternalReference(
ager@chromium.orgea91cc52011-05-23 06:06:11 +00004432 reinterpret_cast<Address *>(FIELD_ADDR(this, kAddressOffset)));
ager@chromium.orgea4f62e2010-08-16 16:28:43 +00004433}
4434
4435
4436void ExternalAsciiString::ExternalAsciiStringIterateBody(ObjectVisitor* v) {
4437 typedef v8::String::ExternalAsciiStringResource Resource;
4438 v->VisitExternalAsciiString(
4439 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4440}
4441
4442
4443template<typename StaticVisitor>
4444void ExternalAsciiString::ExternalAsciiStringIterateBody() {
4445 typedef v8::String::ExternalAsciiStringResource Resource;
4446 StaticVisitor::VisitExternalAsciiString(
4447 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4448}
4449
4450
4451void ExternalTwoByteString::ExternalTwoByteStringIterateBody(ObjectVisitor* v) {
4452 typedef v8::String::ExternalStringResource Resource;
4453 v->VisitExternalTwoByteString(
4454 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4455}
4456
4457
4458template<typename StaticVisitor>
4459void ExternalTwoByteString::ExternalTwoByteStringIterateBody() {
4460 typedef v8::String::ExternalStringResource Resource;
4461 StaticVisitor::VisitExternalTwoByteString(
4462 reinterpret_cast<Resource**>(FIELD_ADDR(this, kResourceOffset)));
4463}
4464
4465#define SLOT_ADDR(obj, offset) \
4466 reinterpret_cast<Object**>((obj)->address() + offset)
4467
4468template<int start_offset, int end_offset, int size>
4469void FixedBodyDescriptor<start_offset, end_offset, size>::IterateBody(
4470 HeapObject* obj,
4471 ObjectVisitor* v) {
4472 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, end_offset));
4473}
4474
4475
4476template<int start_offset>
4477void FlexibleBodyDescriptor<start_offset>::IterateBody(HeapObject* obj,
4478 int object_size,
4479 ObjectVisitor* v) {
4480 v->VisitPointers(SLOT_ADDR(obj, start_offset), SLOT_ADDR(obj, object_size));
4481}
4482
4483#undef SLOT_ADDR
4484
4485
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004486#undef CAST_ACCESSOR
4487#undef INT_ACCESSORS
4488#undef SMI_ACCESSORS
4489#undef ACCESSORS
4490#undef FIELD_ADDR
4491#undef READ_FIELD
4492#undef WRITE_FIELD
4493#undef WRITE_BARRIER
kasperl@chromium.org5a8ca6c2008-10-23 13:57:19 +00004494#undef CONDITIONAL_WRITE_BARRIER
christian.plesner.hansen43d26ec2008-07-03 15:10:15 +00004495#undef READ_MEMADDR_FIELD
4496#undef WRITE_MEMADDR_FIELD
4497#undef READ_DOUBLE_FIELD
4498#undef WRITE_DOUBLE_FIELD
4499#undef READ_INT_FIELD
4500#undef WRITE_INT_FIELD
4501#undef READ_SHORT_FIELD
4502#undef WRITE_SHORT_FIELD
4503#undef READ_BYTE_FIELD
4504#undef WRITE_BYTE_FIELD
4505
4506
4507} } // namespace v8::internal
4508
4509#endif // V8_OBJECTS_INL_H_