OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 the V8 project authors. All rights reserved. |
2 // Redistribution and use in source and binary forms, with or without | 2 // Redistribution and use in source and binary forms, with or without |
3 // modification, are permitted provided that the following conditions are | 3 // modification, are permitted provided that the following conditions are |
4 // met: | 4 // met: |
5 // | 5 // |
6 // * Redistributions of source code must retain the above copyright | 6 // * Redistributions of source code must retain the above copyright |
7 // notice, this list of conditions and the following disclaimer. | 7 // notice, this list of conditions and the following disclaimer. |
8 // * Redistributions in binary form must reproduce the above | 8 // * Redistributions in binary form must reproduce the above |
9 // copyright notice, this list of conditions and the following | 9 // copyright notice, this list of conditions and the following |
10 // disclaimer in the documentation and/or other materials provided | 10 // disclaimer in the documentation and/or other materials provided |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
44 #include "scopeinfo.h" | 44 #include "scopeinfo.h" |
45 #include "string-stream.h" | 45 #include "string-stream.h" |
46 #include "utils.h" | 46 #include "utils.h" |
47 #include "vm-state-inl.h" | 47 #include "vm-state-inl.h" |
48 | 48 |
49 #ifdef ENABLE_DISASSEMBLER | 49 #ifdef ENABLE_DISASSEMBLER |
50 #include "disasm.h" | 50 #include "disasm.h" |
51 #include "disassembler.h" | 51 #include "disassembler.h" |
52 #endif | 52 #endif |
53 | 53 |
54 | |
55 namespace v8 { | 54 namespace v8 { |
56 namespace internal { | 55 namespace internal { |
57 | 56 |
58 // Getters and setters are stored in a fixed array property. These are | 57 // Getters and setters are stored in a fixed array property. These are |
59 // constants for their indices. | 58 // constants for their indices. |
60 const int kGetterIndex = 0; | 59 const int kGetterIndex = 0; |
61 const int kSetterIndex = 1; | 60 const int kSetterIndex = 1; |
62 | 61 |
63 | 62 |
64 MUST_USE_RESULT static MaybeObject* CreateJSValue(JSFunction* constructor, | 63 MUST_USE_RESULT static MaybeObject* CreateJSValue(JSFunction* constructor, |
65 Object* value) { | 64 Object* value) { |
66 Object* result; | 65 Object* result; |
67 { MaybeObject* maybe_result = Heap::AllocateJSObject(constructor); | 66 { MaybeObject* maybe_result = |
| 67 constructor->GetHeap()->AllocateJSObject(constructor); |
68 if (!maybe_result->ToObject(&result)) return maybe_result; | 68 if (!maybe_result->ToObject(&result)) return maybe_result; |
69 } | 69 } |
70 JSValue::cast(result)->set_value(value); | 70 JSValue::cast(result)->set_value(value); |
71 return result; | 71 return result; |
72 } | 72 } |
73 | 73 |
74 | 74 |
75 MaybeObject* Object::ToObject(Context* global_context) { | 75 MaybeObject* Object::ToObject(Context* global_context) { |
76 if (IsNumber()) { | 76 if (IsNumber()) { |
77 return CreateJSValue(global_context->number_function(), this); | 77 return CreateJSValue(global_context->number_function(), this); |
78 } else if (IsBoolean()) { | 78 } else if (IsBoolean()) { |
79 return CreateJSValue(global_context->boolean_function(), this); | 79 return CreateJSValue(global_context->boolean_function(), this); |
80 } else if (IsString()) { | 80 } else if (IsString()) { |
81 return CreateJSValue(global_context->string_function(), this); | 81 return CreateJSValue(global_context->string_function(), this); |
82 } | 82 } |
83 ASSERT(IsJSObject()); | 83 ASSERT(IsJSObject()); |
84 return this; | 84 return this; |
85 } | 85 } |
86 | 86 |
87 | 87 |
88 MaybeObject* Object::ToObject() { | 88 MaybeObject* Object::ToObject() { |
89 Context* global_context = Top::context()->global_context(); | |
90 if (IsJSObject()) { | 89 if (IsJSObject()) { |
91 return this; | 90 return this; |
92 } else if (IsNumber()) { | 91 } else if (IsNumber()) { |
| 92 Isolate* isolate = Isolate::Current(); |
| 93 Context* global_context = isolate->context()->global_context(); |
93 return CreateJSValue(global_context->number_function(), this); | 94 return CreateJSValue(global_context->number_function(), this); |
94 } else if (IsBoolean()) { | 95 } else if (IsBoolean()) { |
| 96 Isolate* isolate = HeapObject::cast(this)->GetIsolate(); |
| 97 Context* global_context = isolate->context()->global_context(); |
95 return CreateJSValue(global_context->boolean_function(), this); | 98 return CreateJSValue(global_context->boolean_function(), this); |
96 } else if (IsString()) { | 99 } else if (IsString()) { |
| 100 Isolate* isolate = HeapObject::cast(this)->GetIsolate(); |
| 101 Context* global_context = isolate->context()->global_context(); |
97 return CreateJSValue(global_context->string_function(), this); | 102 return CreateJSValue(global_context->string_function(), this); |
98 } | 103 } |
99 | 104 |
100 // Throw a type error. | 105 // Throw a type error. |
101 return Failure::InternalError(); | 106 return Failure::InternalError(); |
102 } | 107 } |
103 | 108 |
104 | 109 |
105 Object* Object::ToBoolean() { | 110 Object* Object::ToBoolean() { |
106 if (IsTrue()) return Heap::true_value(); | 111 if (IsTrue()) return this; |
107 if (IsFalse()) return Heap::false_value(); | 112 if (IsFalse()) return this; |
108 if (IsSmi()) { | 113 if (IsSmi()) { |
109 return Heap::ToBoolean(Smi::cast(this)->value() != 0); | 114 return Isolate::Current()->heap()->ToBoolean(Smi::cast(this)->value() != 0); |
110 } | 115 } |
111 if (IsUndefined() || IsNull()) return Heap::false_value(); | 116 if (IsUndefined() || IsNull()) { |
| 117 return HeapObject::cast(this)->GetHeap()->false_value(); |
| 118 } |
112 // Undetectable object is false | 119 // Undetectable object is false |
113 if (IsUndetectableObject()) { | 120 if (IsUndetectableObject()) { |
114 return Heap::false_value(); | 121 return HeapObject::cast(this)->GetHeap()->false_value(); |
115 } | 122 } |
116 if (IsString()) { | 123 if (IsString()) { |
117 return Heap::ToBoolean(String::cast(this)->length() != 0); | 124 return HeapObject::cast(this)->GetHeap()->ToBoolean( |
| 125 String::cast(this)->length() != 0); |
118 } | 126 } |
119 if (IsHeapNumber()) { | 127 if (IsHeapNumber()) { |
120 return HeapNumber::cast(this)->HeapNumberToBoolean(); | 128 return HeapNumber::cast(this)->HeapNumberToBoolean(); |
121 } | 129 } |
122 return Heap::true_value(); | 130 return Isolate::Current()->heap()->true_value(); |
123 } | 131 } |
124 | 132 |
125 | 133 |
126 void Object::Lookup(String* name, LookupResult* result) { | 134 void Object::Lookup(String* name, LookupResult* result) { |
127 if (IsJSObject()) return JSObject::cast(this)->Lookup(name, result); | 135 if (IsJSObject()) return JSObject::cast(this)->Lookup(name, result); |
128 Object* holder = NULL; | 136 Object* holder = NULL; |
129 Context* global_context = Top::context()->global_context(); | |
130 if (IsString()) { | 137 if (IsString()) { |
| 138 Heap* heap = HeapObject::cast(this)->GetHeap(); |
| 139 Context* global_context = heap->isolate()->context()->global_context(); |
131 holder = global_context->string_function()->instance_prototype(); | 140 holder = global_context->string_function()->instance_prototype(); |
132 } else if (IsNumber()) { | 141 } else if (IsNumber()) { |
| 142 Heap* heap = Isolate::Current()->heap(); |
| 143 Context* global_context = heap->isolate()->context()->global_context(); |
133 holder = global_context->number_function()->instance_prototype(); | 144 holder = global_context->number_function()->instance_prototype(); |
134 } else if (IsBoolean()) { | 145 } else if (IsBoolean()) { |
| 146 Heap* heap = HeapObject::cast(this)->GetHeap(); |
| 147 Context* global_context = heap->isolate()->context()->global_context(); |
135 holder = global_context->boolean_function()->instance_prototype(); | 148 holder = global_context->boolean_function()->instance_prototype(); |
136 } | 149 } |
137 ASSERT(holder != NULL); // Cannot handle null or undefined. | 150 ASSERT(holder != NULL); // Cannot handle null or undefined. |
138 JSObject::cast(holder)->Lookup(name, result); | 151 JSObject::cast(holder)->Lookup(name, result); |
139 } | 152 } |
140 | 153 |
141 | 154 |
142 MaybeObject* Object::GetPropertyWithReceiver(Object* receiver, | 155 MaybeObject* Object::GetPropertyWithReceiver(Object* receiver, |
143 String* name, | 156 String* name, |
144 PropertyAttributes* attributes) { | 157 PropertyAttributes* attributes) { |
145 LookupResult result; | 158 LookupResult result; |
146 Lookup(name, &result); | 159 Lookup(name, &result); |
147 MaybeObject* value = GetProperty(receiver, &result, name, attributes); | 160 MaybeObject* value = GetProperty(receiver, &result, name, attributes); |
148 ASSERT(*attributes <= ABSENT); | 161 ASSERT(*attributes <= ABSENT); |
149 return value; | 162 return value; |
150 } | 163 } |
151 | 164 |
152 | 165 |
153 MaybeObject* Object::GetPropertyWithCallback(Object* receiver, | 166 MaybeObject* Object::GetPropertyWithCallback(Object* receiver, |
154 Object* structure, | 167 Object* structure, |
155 String* name, | 168 String* name, |
156 Object* holder) { | 169 Object* holder) { |
| 170 Isolate* isolate = name->GetIsolate(); |
157 // To accommodate both the old and the new api we switch on the | 171 // To accommodate both the old and the new api we switch on the |
158 // data structure used to store the callbacks. Eventually proxy | 172 // data structure used to store the callbacks. Eventually proxy |
159 // callbacks should be phased out. | 173 // callbacks should be phased out. |
160 if (structure->IsProxy()) { | 174 if (structure->IsProxy()) { |
161 AccessorDescriptor* callback = | 175 AccessorDescriptor* callback = |
162 reinterpret_cast<AccessorDescriptor*>(Proxy::cast(structure)->proxy()); | 176 reinterpret_cast<AccessorDescriptor*>(Proxy::cast(structure)->proxy()); |
163 MaybeObject* value = (callback->getter)(receiver, callback->data); | 177 MaybeObject* value = (callback->getter)(receiver, callback->data); |
164 RETURN_IF_SCHEDULED_EXCEPTION(); | 178 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
165 return value; | 179 return value; |
166 } | 180 } |
167 | 181 |
168 // api style callbacks. | 182 // api style callbacks. |
169 if (structure->IsAccessorInfo()) { | 183 if (structure->IsAccessorInfo()) { |
170 AccessorInfo* data = AccessorInfo::cast(structure); | 184 AccessorInfo* data = AccessorInfo::cast(structure); |
171 Object* fun_obj = data->getter(); | 185 Object* fun_obj = data->getter(); |
172 v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj); | 186 v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj); |
173 HandleScope scope; | 187 HandleScope scope; |
174 JSObject* self = JSObject::cast(receiver); | 188 JSObject* self = JSObject::cast(receiver); |
175 JSObject* holder_handle = JSObject::cast(holder); | 189 JSObject* holder_handle = JSObject::cast(holder); |
176 Handle<String> key(name); | 190 Handle<String> key(name); |
177 LOG(ApiNamedPropertyAccess("load", self, name)); | 191 LOG(isolate, ApiNamedPropertyAccess("load", self, name)); |
178 CustomArguments args(data->data(), self, holder_handle); | 192 CustomArguments args(isolate, data->data(), self, holder_handle); |
179 v8::AccessorInfo info(args.end()); | 193 v8::AccessorInfo info(args.end()); |
180 v8::Handle<v8::Value> result; | 194 v8::Handle<v8::Value> result; |
181 { | 195 { |
182 // Leaving JavaScript. | 196 // Leaving JavaScript. |
183 VMState state(EXTERNAL); | 197 VMState state(isolate, EXTERNAL); |
184 result = call_fun(v8::Utils::ToLocal(key), info); | 198 result = call_fun(v8::Utils::ToLocal(key), info); |
185 } | 199 } |
186 RETURN_IF_SCHEDULED_EXCEPTION(); | 200 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
187 if (result.IsEmpty()) return Heap::undefined_value(); | 201 if (result.IsEmpty()) { |
| 202 return isolate->heap()->undefined_value(); |
| 203 } |
188 return *v8::Utils::OpenHandle(*result); | 204 return *v8::Utils::OpenHandle(*result); |
189 } | 205 } |
190 | 206 |
191 // __defineGetter__ callback | 207 // __defineGetter__ callback |
192 if (structure->IsFixedArray()) { | 208 if (structure->IsFixedArray()) { |
193 Object* getter = FixedArray::cast(structure)->get(kGetterIndex); | 209 Object* getter = FixedArray::cast(structure)->get(kGetterIndex); |
194 if (getter->IsJSFunction()) { | 210 if (getter->IsJSFunction()) { |
195 return Object::GetPropertyWithDefinedGetter(receiver, | 211 return Object::GetPropertyWithDefinedGetter(receiver, |
196 JSFunction::cast(getter)); | 212 JSFunction::cast(getter)); |
197 } | 213 } |
198 // Getter is not a function. | 214 // Getter is not a function. |
199 return Heap::undefined_value(); | 215 return isolate->heap()->undefined_value(); |
200 } | 216 } |
201 | 217 |
202 UNREACHABLE(); | 218 UNREACHABLE(); |
203 return NULL; | 219 return NULL; |
204 } | 220 } |
205 | 221 |
206 | 222 |
207 MaybeObject* Object::GetPropertyWithDefinedGetter(Object* receiver, | 223 MaybeObject* Object::GetPropertyWithDefinedGetter(Object* receiver, |
208 JSFunction* getter) { | 224 JSFunction* getter) { |
209 HandleScope scope; | 225 HandleScope scope; |
210 Handle<JSFunction> fun(JSFunction::cast(getter)); | 226 Handle<JSFunction> fun(JSFunction::cast(getter)); |
211 Handle<Object> self(receiver); | 227 Handle<Object> self(receiver); |
212 #ifdef ENABLE_DEBUGGER_SUPPORT | 228 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 229 Debug* debug = fun->GetHeap()->isolate()->debug(); |
213 // Handle stepping into a getter if step into is active. | 230 // Handle stepping into a getter if step into is active. |
214 if (Debug::StepInActive()) { | 231 if (debug->StepInActive()) { |
215 Debug::HandleStepIn(fun, Handle<Object>::null(), 0, false); | 232 debug->HandleStepIn(fun, Handle<Object>::null(), 0, false); |
216 } | 233 } |
217 #endif | 234 #endif |
218 bool has_pending_exception; | 235 bool has_pending_exception; |
219 Handle<Object> result = | 236 Handle<Object> result = |
220 Execution::Call(fun, self, 0, NULL, &has_pending_exception); | 237 Execution::Call(fun, self, 0, NULL, &has_pending_exception); |
221 // Check for pending exception and return the result. | 238 // Check for pending exception and return the result. |
222 if (has_pending_exception) return Failure::Exception(); | 239 if (has_pending_exception) return Failure::Exception(); |
223 return *result; | 240 return *result; |
224 } | 241 } |
225 | 242 |
226 | 243 |
227 // Only deal with CALLBACKS and INTERCEPTOR | 244 // Only deal with CALLBACKS and INTERCEPTOR |
228 MaybeObject* JSObject::GetPropertyWithFailedAccessCheck( | 245 MaybeObject* JSObject::GetPropertyWithFailedAccessCheck( |
229 Object* receiver, | 246 Object* receiver, |
230 LookupResult* result, | 247 LookupResult* result, |
231 String* name, | 248 String* name, |
232 PropertyAttributes* attributes) { | 249 PropertyAttributes* attributes) { |
| 250 Heap* heap = name->GetHeap(); |
233 if (result->IsProperty()) { | 251 if (result->IsProperty()) { |
234 switch (result->type()) { | 252 switch (result->type()) { |
235 case CALLBACKS: { | 253 case CALLBACKS: { |
236 // Only allow API accessors. | 254 // Only allow API accessors. |
237 Object* obj = result->GetCallbackObject(); | 255 Object* obj = result->GetCallbackObject(); |
238 if (obj->IsAccessorInfo()) { | 256 if (obj->IsAccessorInfo()) { |
239 AccessorInfo* info = AccessorInfo::cast(obj); | 257 AccessorInfo* info = AccessorInfo::cast(obj); |
240 if (info->all_can_read()) { | 258 if (info->all_can_read()) { |
241 *attributes = result->GetAttributes(); | 259 *attributes = result->GetAttributes(); |
242 return GetPropertyWithCallback(receiver, | 260 return GetPropertyWithCallback(receiver, |
(...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
274 } | 292 } |
275 break; | 293 break; |
276 } | 294 } |
277 default: | 295 default: |
278 UNREACHABLE(); | 296 UNREACHABLE(); |
279 } | 297 } |
280 } | 298 } |
281 | 299 |
282 // No accessible property found. | 300 // No accessible property found. |
283 *attributes = ABSENT; | 301 *attributes = ABSENT; |
284 Top::ReportFailedAccessCheck(this, v8::ACCESS_GET); | 302 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_GET); |
285 return Heap::undefined_value(); | 303 return heap->undefined_value(); |
286 } | 304 } |
287 | 305 |
288 | 306 |
289 PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck( | 307 PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck( |
290 Object* receiver, | 308 Object* receiver, |
291 LookupResult* result, | 309 LookupResult* result, |
292 String* name, | 310 String* name, |
293 bool continue_search) { | 311 bool continue_search) { |
| 312 Heap* heap = name->GetHeap(); |
294 if (result->IsProperty()) { | 313 if (result->IsProperty()) { |
295 switch (result->type()) { | 314 switch (result->type()) { |
296 case CALLBACKS: { | 315 case CALLBACKS: { |
297 // Only allow API accessors. | 316 // Only allow API accessors. |
298 Object* obj = result->GetCallbackObject(); | 317 Object* obj = result->GetCallbackObject(); |
299 if (obj->IsAccessorInfo()) { | 318 if (obj->IsAccessorInfo()) { |
300 AccessorInfo* info = AccessorInfo::cast(obj); | 319 AccessorInfo* info = AccessorInfo::cast(obj); |
301 if (info->all_can_read()) { | 320 if (info->all_can_read()) { |
302 return result->GetAttributes(); | 321 return result->GetAttributes(); |
303 } | 322 } |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
337 continue_search); | 356 continue_search); |
338 } | 357 } |
339 break; | 358 break; |
340 } | 359 } |
341 | 360 |
342 default: | 361 default: |
343 UNREACHABLE(); | 362 UNREACHABLE(); |
344 } | 363 } |
345 } | 364 } |
346 | 365 |
347 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 366 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
348 return ABSENT; | 367 return ABSENT; |
349 } | 368 } |
350 | 369 |
351 | 370 |
352 Object* JSObject::GetNormalizedProperty(LookupResult* result) { | 371 Object* JSObject::GetNormalizedProperty(LookupResult* result) { |
353 ASSERT(!HasFastProperties()); | 372 ASSERT(!HasFastProperties()); |
354 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); | 373 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); |
355 if (IsGlobalObject()) { | 374 if (IsGlobalObject()) { |
356 value = JSGlobalPropertyCell::cast(value)->value(); | 375 value = JSGlobalPropertyCell::cast(value)->value(); |
357 } | 376 } |
(...skipping 13 matching lines...) Expand all Loading... |
371 property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value); | 390 property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value); |
372 } | 391 } |
373 return value; | 392 return value; |
374 } | 393 } |
375 | 394 |
376 | 395 |
377 MaybeObject* JSObject::SetNormalizedProperty(String* name, | 396 MaybeObject* JSObject::SetNormalizedProperty(String* name, |
378 Object* value, | 397 Object* value, |
379 PropertyDetails details) { | 398 PropertyDetails details) { |
380 ASSERT(!HasFastProperties()); | 399 ASSERT(!HasFastProperties()); |
| 400 Heap* heap = name->GetHeap(); |
381 int entry = property_dictionary()->FindEntry(name); | 401 int entry = property_dictionary()->FindEntry(name); |
382 if (entry == StringDictionary::kNotFound) { | 402 if (entry == StringDictionary::kNotFound) { |
383 Object* store_value = value; | 403 Object* store_value = value; |
384 if (IsGlobalObject()) { | 404 if (IsGlobalObject()) { |
385 { MaybeObject* maybe_store_value = | 405 MaybeObject* maybe_store_value = |
386 Heap::AllocateJSGlobalPropertyCell(value); | 406 heap->AllocateJSGlobalPropertyCell(value); |
387 if (!maybe_store_value->ToObject(&store_value)) { | 407 if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value; |
388 return maybe_store_value; | |
389 } | |
390 } | |
391 } | 408 } |
392 Object* dict; | 409 Object* dict; |
393 { MaybeObject* maybe_dict = | 410 { MaybeObject* maybe_dict = |
394 property_dictionary()->Add(name, store_value, details); | 411 property_dictionary()->Add(name, store_value, details); |
395 if (!maybe_dict->ToObject(&dict)) return maybe_dict; | 412 if (!maybe_dict->ToObject(&dict)) return maybe_dict; |
396 } | 413 } |
397 set_properties(StringDictionary::cast(dict)); | 414 set_properties(StringDictionary::cast(dict)); |
398 return value; | 415 return value; |
399 } | 416 } |
400 // Preserve enumeration index. | 417 // Preserve enumeration index. |
401 details = PropertyDetails(details.attributes(), | 418 details = PropertyDetails(details.attributes(), |
402 details.type(), | 419 details.type(), |
403 property_dictionary()->DetailsAt(entry).index()); | 420 property_dictionary()->DetailsAt(entry).index()); |
404 if (IsGlobalObject()) { | 421 if (IsGlobalObject()) { |
405 JSGlobalPropertyCell* cell = | 422 JSGlobalPropertyCell* cell = |
406 JSGlobalPropertyCell::cast(property_dictionary()->ValueAt(entry)); | 423 JSGlobalPropertyCell::cast(property_dictionary()->ValueAt(entry)); |
407 cell->set_value(value); | 424 cell->set_value(value); |
408 // Please note we have to update the property details. | 425 // Please note we have to update the property details. |
409 property_dictionary()->DetailsAtPut(entry, details); | 426 property_dictionary()->DetailsAtPut(entry, details); |
410 } else { | 427 } else { |
411 property_dictionary()->SetEntry(entry, name, value, details); | 428 property_dictionary()->SetEntry(entry, name, value, details); |
412 } | 429 } |
413 return value; | 430 return value; |
414 } | 431 } |
415 | 432 |
416 | 433 |
417 MaybeObject* JSObject::DeleteNormalizedProperty(String* name, DeleteMode mode) { | 434 MaybeObject* JSObject::DeleteNormalizedProperty(String* name, DeleteMode mode) { |
418 ASSERT(!HasFastProperties()); | 435 ASSERT(!HasFastProperties()); |
| 436 Heap* heap = GetHeap(); |
419 StringDictionary* dictionary = property_dictionary(); | 437 StringDictionary* dictionary = property_dictionary(); |
420 int entry = dictionary->FindEntry(name); | 438 int entry = dictionary->FindEntry(name); |
421 if (entry != StringDictionary::kNotFound) { | 439 if (entry != StringDictionary::kNotFound) { |
422 // If we have a global object set the cell to the hole. | 440 // If we have a global object set the cell to the hole. |
423 if (IsGlobalObject()) { | 441 if (IsGlobalObject()) { |
424 PropertyDetails details = dictionary->DetailsAt(entry); | 442 PropertyDetails details = dictionary->DetailsAt(entry); |
425 if (details.IsDontDelete()) { | 443 if (details.IsDontDelete()) { |
426 if (mode != FORCE_DELETION) return Heap::false_value(); | 444 if (mode != FORCE_DELETION) return heap->false_value(); |
427 // When forced to delete global properties, we have to make a | 445 // When forced to delete global properties, we have to make a |
428 // map change to invalidate any ICs that think they can load | 446 // map change to invalidate any ICs that think they can load |
429 // from the DontDelete cell without checking if it contains | 447 // from the DontDelete cell without checking if it contains |
430 // the hole value. | 448 // the hole value. |
431 Object* new_map; | 449 Object* new_map; |
432 { MaybeObject* maybe_new_map = map()->CopyDropDescriptors(); | 450 { MaybeObject* maybe_new_map = map()->CopyDropDescriptors(); |
433 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; | 451 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; |
434 } | 452 } |
435 set_map(Map::cast(new_map)); | 453 set_map(Map::cast(new_map)); |
436 } | 454 } |
437 JSGlobalPropertyCell* cell = | 455 JSGlobalPropertyCell* cell = |
438 JSGlobalPropertyCell::cast(dictionary->ValueAt(entry)); | 456 JSGlobalPropertyCell::cast(dictionary->ValueAt(entry)); |
439 cell->set_value(Heap::the_hole_value()); | 457 cell->set_value(heap->the_hole_value()); |
440 dictionary->DetailsAtPut(entry, details.AsDeleted()); | 458 dictionary->DetailsAtPut(entry, details.AsDeleted()); |
441 } else { | 459 } else { |
442 return dictionary->DeleteProperty(entry, mode); | 460 return dictionary->DeleteProperty(entry, mode); |
443 } | 461 } |
444 } | 462 } |
445 return Heap::true_value(); | 463 return heap->true_value(); |
446 } | 464 } |
447 | 465 |
448 | 466 |
449 bool JSObject::IsDirty() { | 467 bool JSObject::IsDirty() { |
450 Object* cons_obj = map()->constructor(); | 468 Object* cons_obj = map()->constructor(); |
451 if (!cons_obj->IsJSFunction()) | 469 if (!cons_obj->IsJSFunction()) |
452 return true; | 470 return true; |
453 JSFunction* fun = JSFunction::cast(cons_obj); | 471 JSFunction* fun = JSFunction::cast(cons_obj); |
454 if (!fun->shared()->IsApiFunction()) | 472 if (!fun->shared()->IsApiFunction()) |
455 return true; | 473 return true; |
456 // If the object is fully fast case and has the same map it was | 474 // If the object is fully fast case and has the same map it was |
457 // created with then no changes can have been made to it. | 475 // created with then no changes can have been made to it. |
458 return map() != fun->initial_map() | 476 return map() != fun->initial_map() |
459 || !HasFastElements() | 477 || !HasFastElements() |
460 || !HasFastProperties(); | 478 || !HasFastProperties(); |
461 } | 479 } |
462 | 480 |
463 | 481 |
464 MaybeObject* Object::GetProperty(Object* receiver, | 482 MaybeObject* Object::GetProperty(Object* receiver, |
465 LookupResult* result, | 483 LookupResult* result, |
466 String* name, | 484 String* name, |
467 PropertyAttributes* attributes) { | 485 PropertyAttributes* attributes) { |
468 // Make sure that the top context does not change when doing | 486 // Make sure that the top context does not change when doing |
469 // callbacks or interceptor calls. | 487 // callbacks or interceptor calls. |
470 AssertNoContextChange ncc; | 488 AssertNoContextChange ncc; |
| 489 Heap* heap = name->GetHeap(); |
471 | 490 |
472 // Traverse the prototype chain from the current object (this) to | 491 // Traverse the prototype chain from the current object (this) to |
473 // the holder and check for access rights. This avoid traversing the | 492 // the holder and check for access rights. This avoid traversing the |
474 // objects more than once in case of interceptors, because the | 493 // objects more than once in case of interceptors, because the |
475 // holder will always be the interceptor holder and the search may | 494 // holder will always be the interceptor holder and the search may |
476 // only continue with a current object just after the interceptor | 495 // only continue with a current object just after the interceptor |
477 // holder in the prototype chain. | 496 // holder in the prototype chain. |
478 Object* last = result->IsProperty() ? result->holder() : Heap::null_value(); | 497 Object* last = result->IsProperty() ? result->holder() : heap->null_value(); |
479 for (Object* current = this; true; current = current->GetPrototype()) { | 498 for (Object* current = this; true; current = current->GetPrototype()) { |
480 if (current->IsAccessCheckNeeded()) { | 499 if (current->IsAccessCheckNeeded()) { |
481 // Check if we're allowed to read from the current object. Note | 500 // Check if we're allowed to read from the current object. Note |
482 // that even though we may not actually end up loading the named | 501 // that even though we may not actually end up loading the named |
483 // property from the current object, we still check that we have | 502 // property from the current object, we still check that we have |
484 // access to it. | 503 // access to it. |
485 JSObject* checked = JSObject::cast(current); | 504 JSObject* checked = JSObject::cast(current); |
486 if (!Top::MayNamedAccess(checked, name, v8::ACCESS_GET)) { | 505 if (!heap->isolate()->MayNamedAccess(checked, name, v8::ACCESS_GET)) { |
487 return checked->GetPropertyWithFailedAccessCheck(receiver, | 506 return checked->GetPropertyWithFailedAccessCheck(receiver, |
488 result, | 507 result, |
489 name, | 508 name, |
490 attributes); | 509 attributes); |
491 } | 510 } |
492 } | 511 } |
493 // Stop traversing the chain once we reach the last object in the | 512 // Stop traversing the chain once we reach the last object in the |
494 // chain; either the holder of the result or null in case of an | 513 // chain; either the holder of the result or null in case of an |
495 // absent property. | 514 // absent property. |
496 if (current == last) break; | 515 if (current == last) break; |
497 } | 516 } |
498 | 517 |
499 if (!result->IsProperty()) { | 518 if (!result->IsProperty()) { |
500 *attributes = ABSENT; | 519 *attributes = ABSENT; |
501 return Heap::undefined_value(); | 520 return heap->undefined_value(); |
502 } | 521 } |
503 *attributes = result->GetAttributes(); | 522 *attributes = result->GetAttributes(); |
504 Object* value; | 523 Object* value; |
505 JSObject* holder = result->holder(); | 524 JSObject* holder = result->holder(); |
506 switch (result->type()) { | 525 switch (result->type()) { |
507 case NORMAL: | 526 case NORMAL: |
508 value = holder->GetNormalizedProperty(result); | 527 value = holder->GetNormalizedProperty(result); |
509 ASSERT(!value->IsTheHole() || result->IsReadOnly()); | 528 ASSERT(!value->IsTheHole() || result->IsReadOnly()); |
510 return value->IsTheHole() ? Heap::undefined_value() : value; | 529 return value->IsTheHole() ? heap->undefined_value() : value; |
511 case FIELD: | 530 case FIELD: |
512 value = holder->FastPropertyAt(result->GetFieldIndex()); | 531 value = holder->FastPropertyAt(result->GetFieldIndex()); |
513 ASSERT(!value->IsTheHole() || result->IsReadOnly()); | 532 ASSERT(!value->IsTheHole() || result->IsReadOnly()); |
514 return value->IsTheHole() ? Heap::undefined_value() : value; | 533 return value->IsTheHole() ? heap->undefined_value() : value; |
515 case CONSTANT_FUNCTION: | 534 case CONSTANT_FUNCTION: |
516 return result->GetConstantFunction(); | 535 return result->GetConstantFunction(); |
517 case CALLBACKS: | 536 case CALLBACKS: |
518 return GetPropertyWithCallback(receiver, | 537 return GetPropertyWithCallback(receiver, |
519 result->GetCallbackObject(), | 538 result->GetCallbackObject(), |
520 name, | 539 name, |
521 holder); | 540 holder); |
522 case INTERCEPTOR: { | 541 case INTERCEPTOR: { |
523 JSObject* recvr = JSObject::cast(receiver); | 542 JSObject* recvr = JSObject::cast(receiver); |
524 return holder->GetPropertyWithInterceptor(recvr, name, attributes); | 543 return holder->GetPropertyWithInterceptor(recvr, name, attributes); |
525 } | 544 } |
526 default: | 545 default: |
527 UNREACHABLE(); | 546 UNREACHABLE(); |
528 return NULL; | 547 return NULL; |
529 } | 548 } |
530 } | 549 } |
531 | 550 |
532 | 551 |
533 MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) { | 552 MaybeObject* Object::GetElementWithReceiver(Object* receiver, uint32_t index) { |
534 if (IsJSObject()) { | 553 if (IsJSObject()) { |
535 return JSObject::cast(this)->GetElementWithReceiver(receiver, index); | 554 return JSObject::cast(this)->GetElementWithReceiver(receiver, index); |
536 } | 555 } |
537 | 556 |
538 Object* holder = NULL; | 557 Object* holder = NULL; |
539 Context* global_context = Top::context()->global_context(); | 558 Context* global_context = Isolate::Current()->context()->global_context(); |
540 if (IsString()) { | 559 if (IsString()) { |
541 holder = global_context->string_function()->instance_prototype(); | 560 holder = global_context->string_function()->instance_prototype(); |
542 } else if (IsNumber()) { | 561 } else if (IsNumber()) { |
543 holder = global_context->number_function()->instance_prototype(); | 562 holder = global_context->number_function()->instance_prototype(); |
544 } else if (IsBoolean()) { | 563 } else if (IsBoolean()) { |
545 holder = global_context->boolean_function()->instance_prototype(); | 564 holder = global_context->boolean_function()->instance_prototype(); |
546 } else { | 565 } else { |
547 // Undefined and null have no indexed properties. | 566 // Undefined and null have no indexed properties. |
548 ASSERT(IsUndefined() || IsNull()); | 567 ASSERT(IsUndefined() || IsNull()); |
549 return Heap::undefined_value(); | 568 return HEAP->undefined_value(); |
550 } | 569 } |
551 | 570 |
552 return JSObject::cast(holder)->GetElementWithReceiver(receiver, index); | 571 return JSObject::cast(holder)->GetElementWithReceiver(receiver, index); |
553 } | 572 } |
554 | 573 |
555 | 574 |
556 Object* Object::GetPrototype() { | 575 Object* Object::GetPrototype() { |
557 // The object is either a number, a string, a boolean, or a real JS object. | 576 // The object is either a number, a string, a boolean, or a real JS object. |
558 if (IsJSObject()) return JSObject::cast(this)->map()->prototype(); | 577 if (IsJSObject()) return JSObject::cast(this)->map()->prototype(); |
559 Context* context = Top::context()->global_context(); | 578 Heap* heap = Isolate::Current()->heap(); |
| 579 Context* context = heap->isolate()->context()->global_context(); |
560 | 580 |
561 if (IsNumber()) return context->number_function()->instance_prototype(); | 581 if (IsNumber()) return context->number_function()->instance_prototype(); |
562 if (IsString()) return context->string_function()->instance_prototype(); | 582 if (IsString()) return context->string_function()->instance_prototype(); |
563 if (IsBoolean()) { | 583 if (IsBoolean()) { |
564 return context->boolean_function()->instance_prototype(); | 584 return context->boolean_function()->instance_prototype(); |
565 } else { | 585 } else { |
566 return Heap::null_value(); | 586 return heap->null_value(); |
567 } | 587 } |
568 } | 588 } |
569 | 589 |
570 | 590 |
571 void Object::ShortPrint(FILE* out) { | 591 void Object::ShortPrint(FILE* out) { |
572 HeapStringAllocator allocator; | 592 HeapStringAllocator allocator; |
573 StringStream accumulator(&allocator); | 593 StringStream accumulator(&allocator); |
574 ShortPrint(&accumulator); | 594 ShortPrint(&accumulator); |
575 accumulator.OutputToFile(out); | 595 accumulator.OutputToFile(out); |
576 } | 596 } |
(...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
630 return false; | 650 return false; |
631 } | 651 } |
632 | 652 |
633 | 653 |
634 MaybeObject* String::SlowTryFlatten(PretenureFlag pretenure) { | 654 MaybeObject* String::SlowTryFlatten(PretenureFlag pretenure) { |
635 #ifdef DEBUG | 655 #ifdef DEBUG |
636 // Do not attempt to flatten in debug mode when allocation is not | 656 // Do not attempt to flatten in debug mode when allocation is not |
637 // allowed. This is to avoid an assertion failure when allocating. | 657 // allowed. This is to avoid an assertion failure when allocating. |
638 // Flattening strings is the only case where we always allow | 658 // Flattening strings is the only case where we always allow |
639 // allocation because no GC is performed if the allocation fails. | 659 // allocation because no GC is performed if the allocation fails. |
640 if (!Heap::IsAllocationAllowed()) return this; | 660 if (!HEAP->IsAllocationAllowed()) return this; |
641 #endif | 661 #endif |
642 | 662 |
| 663 Heap* heap = GetHeap(); |
643 switch (StringShape(this).representation_tag()) { | 664 switch (StringShape(this).representation_tag()) { |
644 case kConsStringTag: { | 665 case kConsStringTag: { |
645 ConsString* cs = ConsString::cast(this); | 666 ConsString* cs = ConsString::cast(this); |
646 if (cs->second()->length() == 0) { | 667 if (cs->second()->length() == 0) { |
647 return cs->first(); | 668 return cs->first(); |
648 } | 669 } |
649 // There's little point in putting the flat string in new space if the | 670 // There's little point in putting the flat string in new space if the |
650 // cons string is in old space. It can never get GCed until there is | 671 // cons string is in old space. It can never get GCed until there is |
651 // an old space GC. | 672 // an old space GC. |
652 PretenureFlag tenure = Heap::InNewSpace(this) ? pretenure : TENURED; | 673 PretenureFlag tenure = heap->InNewSpace(this) ? pretenure : TENURED; |
653 int len = length(); | 674 int len = length(); |
654 Object* object; | 675 Object* object; |
655 String* result; | 676 String* result; |
656 if (IsAsciiRepresentation()) { | 677 if (IsAsciiRepresentation()) { |
657 { MaybeObject* maybe_object = Heap::AllocateRawAsciiString(len, tenure); | 678 { MaybeObject* maybe_object = heap->AllocateRawAsciiString(len, tenure); |
658 if (!maybe_object->ToObject(&object)) return maybe_object; | 679 if (!maybe_object->ToObject(&object)) return maybe_object; |
659 } | 680 } |
660 result = String::cast(object); | 681 result = String::cast(object); |
661 String* first = cs->first(); | 682 String* first = cs->first(); |
662 int first_length = first->length(); | 683 int first_length = first->length(); |
663 char* dest = SeqAsciiString::cast(result)->GetChars(); | 684 char* dest = SeqAsciiString::cast(result)->GetChars(); |
664 WriteToFlat(first, dest, 0, first_length); | 685 WriteToFlat(first, dest, 0, first_length); |
665 String* second = cs->second(); | 686 String* second = cs->second(); |
666 WriteToFlat(second, | 687 WriteToFlat(second, |
667 dest + first_length, | 688 dest + first_length, |
668 0, | 689 0, |
669 len - first_length); | 690 len - first_length); |
670 } else { | 691 } else { |
671 { MaybeObject* maybe_object = | 692 { MaybeObject* maybe_object = |
672 Heap::AllocateRawTwoByteString(len, tenure); | 693 heap->AllocateRawTwoByteString(len, tenure); |
673 if (!maybe_object->ToObject(&object)) return maybe_object; | 694 if (!maybe_object->ToObject(&object)) return maybe_object; |
674 } | 695 } |
675 result = String::cast(object); | 696 result = String::cast(object); |
676 uc16* dest = SeqTwoByteString::cast(result)->GetChars(); | 697 uc16* dest = SeqTwoByteString::cast(result)->GetChars(); |
677 String* first = cs->first(); | 698 String* first = cs->first(); |
678 int first_length = first->length(); | 699 int first_length = first->length(); |
679 WriteToFlat(first, dest, 0, first_length); | 700 WriteToFlat(first, dest, 0, first_length); |
680 String* second = cs->second(); | 701 String* second = cs->second(); |
681 WriteToFlat(second, | 702 WriteToFlat(second, |
682 dest + first_length, | 703 dest + first_length, |
683 0, | 704 0, |
684 len - first_length); | 705 len - first_length); |
685 } | 706 } |
686 cs->set_first(result); | 707 cs->set_first(result); |
687 cs->set_second(Heap::empty_string()); | 708 cs->set_second(heap->empty_string()); |
688 return result; | 709 return result; |
689 } | 710 } |
690 default: | 711 default: |
691 return this; | 712 return this; |
692 } | 713 } |
693 } | 714 } |
694 | 715 |
695 | 716 |
696 bool String::MakeExternal(v8::String::ExternalStringResource* resource) { | 717 bool String::MakeExternal(v8::String::ExternalStringResource* resource) { |
697 // Externalizing twice leaks the external resource, so it's | 718 // Externalizing twice leaks the external resource, so it's |
698 // prohibited by the API. | 719 // prohibited by the API. |
699 ASSERT(!this->IsExternalString()); | 720 ASSERT(!this->IsExternalString()); |
700 #ifdef DEBUG | 721 #ifdef DEBUG |
701 if (FLAG_enable_slow_asserts) { | 722 if (FLAG_enable_slow_asserts) { |
702 // Assert that the resource and the string are equivalent. | 723 // Assert that the resource and the string are equivalent. |
703 ASSERT(static_cast<size_t>(this->length()) == resource->length()); | 724 ASSERT(static_cast<size_t>(this->length()) == resource->length()); |
704 ScopedVector<uc16> smart_chars(this->length()); | 725 ScopedVector<uc16> smart_chars(this->length()); |
705 String::WriteToFlat(this, smart_chars.start(), 0, this->length()); | 726 String::WriteToFlat(this, smart_chars.start(), 0, this->length()); |
706 ASSERT(memcmp(smart_chars.start(), | 727 ASSERT(memcmp(smart_chars.start(), |
707 resource->data(), | 728 resource->data(), |
708 resource->length() * sizeof(smart_chars[0])) == 0); | 729 resource->length() * sizeof(smart_chars[0])) == 0); |
709 } | 730 } |
710 #endif // DEBUG | 731 #endif // DEBUG |
711 | 732 Heap* heap = GetHeap(); |
712 int size = this->Size(); // Byte size of the original string. | 733 int size = this->Size(); // Byte size of the original string. |
713 if (size < ExternalString::kSize) { | 734 if (size < ExternalString::kSize) { |
714 // The string is too small to fit an external String in its place. This can | 735 // The string is too small to fit an external String in its place. This can |
715 // only happen for zero length strings. | 736 // only happen for zero length strings. |
716 return false; | 737 return false; |
717 } | 738 } |
718 ASSERT(size >= ExternalString::kSize); | 739 ASSERT(size >= ExternalString::kSize); |
719 bool is_ascii = this->IsAsciiRepresentation(); | 740 bool is_ascii = this->IsAsciiRepresentation(); |
720 bool is_symbol = this->IsSymbol(); | 741 bool is_symbol = this->IsSymbol(); |
721 int length = this->length(); | 742 int length = this->length(); |
722 int hash_field = this->hash_field(); | 743 int hash_field = this->hash_field(); |
723 | 744 |
724 // Morph the object to an external string by adjusting the map and | 745 // Morph the object to an external string by adjusting the map and |
725 // reinitializing the fields. | 746 // reinitializing the fields. |
726 this->set_map(is_ascii ? | 747 this->set_map(is_ascii ? |
727 Heap::external_string_with_ascii_data_map() : | 748 heap->external_string_with_ascii_data_map() : |
728 Heap::external_string_map()); | 749 heap->external_string_map()); |
729 ExternalTwoByteString* self = ExternalTwoByteString::cast(this); | 750 ExternalTwoByteString* self = ExternalTwoByteString::cast(this); |
730 self->set_length(length); | 751 self->set_length(length); |
731 self->set_hash_field(hash_field); | 752 self->set_hash_field(hash_field); |
732 self->set_resource(resource); | 753 self->set_resource(resource); |
733 // Additionally make the object into an external symbol if the original string | 754 // Additionally make the object into an external symbol if the original string |
734 // was a symbol to start with. | 755 // was a symbol to start with. |
735 if (is_symbol) { | 756 if (is_symbol) { |
736 self->Hash(); // Force regeneration of the hash value. | 757 self->Hash(); // Force regeneration of the hash value. |
737 // Now morph this external string into a external symbol. | 758 // Now morph this external string into a external symbol. |
738 this->set_map(is_ascii ? | 759 this->set_map(is_ascii ? |
739 Heap::external_symbol_with_ascii_data_map() : | 760 heap->external_symbol_with_ascii_data_map() : |
740 Heap::external_symbol_map()); | 761 heap->external_symbol_map()); |
741 } | 762 } |
742 | 763 |
743 // Fill the remainder of the string with dead wood. | 764 // Fill the remainder of the string with dead wood. |
744 int new_size = this->Size(); // Byte size of the external String object. | 765 int new_size = this->Size(); // Byte size of the external String object. |
745 Heap::CreateFillerObjectAt(this->address() + new_size, size - new_size); | 766 heap->CreateFillerObjectAt(this->address() + new_size, size - new_size); |
746 return true; | 767 return true; |
747 } | 768 } |
748 | 769 |
749 | 770 |
750 bool String::MakeExternal(v8::String::ExternalAsciiStringResource* resource) { | 771 bool String::MakeExternal(v8::String::ExternalAsciiStringResource* resource) { |
751 #ifdef DEBUG | 772 #ifdef DEBUG |
752 if (FLAG_enable_slow_asserts) { | 773 if (FLAG_enable_slow_asserts) { |
753 // Assert that the resource and the string are equivalent. | 774 // Assert that the resource and the string are equivalent. |
754 ASSERT(static_cast<size_t>(this->length()) == resource->length()); | 775 ASSERT(static_cast<size_t>(this->length()) == resource->length()); |
755 ScopedVector<char> smart_chars(this->length()); | 776 ScopedVector<char> smart_chars(this->length()); |
756 String::WriteToFlat(this, smart_chars.start(), 0, this->length()); | 777 String::WriteToFlat(this, smart_chars.start(), 0, this->length()); |
757 ASSERT(memcmp(smart_chars.start(), | 778 ASSERT(memcmp(smart_chars.start(), |
758 resource->data(), | 779 resource->data(), |
759 resource->length() * sizeof(smart_chars[0])) == 0); | 780 resource->length() * sizeof(smart_chars[0])) == 0); |
760 } | 781 } |
761 #endif // DEBUG | 782 #endif // DEBUG |
762 | 783 Heap* heap = GetHeap(); |
763 int size = this->Size(); // Byte size of the original string. | 784 int size = this->Size(); // Byte size of the original string. |
764 if (size < ExternalString::kSize) { | 785 if (size < ExternalString::kSize) { |
765 // The string is too small to fit an external String in its place. This can | 786 // The string is too small to fit an external String in its place. This can |
766 // only happen for zero length strings. | 787 // only happen for zero length strings. |
767 return false; | 788 return false; |
768 } | 789 } |
769 ASSERT(size >= ExternalString::kSize); | 790 ASSERT(size >= ExternalString::kSize); |
770 bool is_symbol = this->IsSymbol(); | 791 bool is_symbol = this->IsSymbol(); |
771 int length = this->length(); | 792 int length = this->length(); |
772 int hash_field = this->hash_field(); | 793 int hash_field = this->hash_field(); |
773 | 794 |
774 // Morph the object to an external string by adjusting the map and | 795 // Morph the object to an external string by adjusting the map and |
775 // reinitializing the fields. | 796 // reinitializing the fields. |
776 this->set_map(Heap::external_ascii_string_map()); | 797 this->set_map(heap->external_ascii_string_map()); |
777 ExternalAsciiString* self = ExternalAsciiString::cast(this); | 798 ExternalAsciiString* self = ExternalAsciiString::cast(this); |
778 self->set_length(length); | 799 self->set_length(length); |
779 self->set_hash_field(hash_field); | 800 self->set_hash_field(hash_field); |
780 self->set_resource(resource); | 801 self->set_resource(resource); |
781 // Additionally make the object into an external symbol if the original string | 802 // Additionally make the object into an external symbol if the original string |
782 // was a symbol to start with. | 803 // was a symbol to start with. |
783 if (is_symbol) { | 804 if (is_symbol) { |
784 self->Hash(); // Force regeneration of the hash value. | 805 self->Hash(); // Force regeneration of the hash value. |
785 // Now morph this external string into a external symbol. | 806 // Now morph this external string into a external symbol. |
786 this->set_map(Heap::external_ascii_symbol_map()); | 807 this->set_map(heap->external_ascii_symbol_map()); |
787 } | 808 } |
788 | 809 |
789 // Fill the remainder of the string with dead wood. | 810 // Fill the remainder of the string with dead wood. |
790 int new_size = this->Size(); // Byte size of the external String object. | 811 int new_size = this->Size(); // Byte size of the external String object. |
791 Heap::CreateFillerObjectAt(this->address() + new_size, size - new_size); | 812 heap->CreateFillerObjectAt(this->address() + new_size, size - new_size); |
792 return true; | 813 return true; |
793 } | 814 } |
794 | 815 |
795 | 816 |
796 void String::StringShortPrint(StringStream* accumulator) { | 817 void String::StringShortPrint(StringStream* accumulator) { |
797 int len = length(); | 818 int len = length(); |
798 if (len > kMaxShortPrintLength) { | 819 if (len > kMaxShortPrintLength) { |
799 accumulator->Add("<Very long string[%u]>", len); | 820 accumulator->Add("<Very long string[%u]>", len); |
800 return; | 821 return; |
801 } | 822 } |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
880 } | 901 } |
881 } | 902 } |
882 if (!printed) { | 903 if (!printed) { |
883 accumulator->Add("<JS Function>"); | 904 accumulator->Add("<JS Function>"); |
884 } | 905 } |
885 break; | 906 break; |
886 } | 907 } |
887 // All other JSObjects are rather similar to each other (JSObject, | 908 // All other JSObjects are rather similar to each other (JSObject, |
888 // JSGlobalProxy, JSGlobalObject, JSUndetectableObject, JSValue). | 909 // JSGlobalProxy, JSGlobalObject, JSUndetectableObject, JSValue). |
889 default: { | 910 default: { |
| 911 Heap* heap = GetHeap(); |
890 Object* constructor = map()->constructor(); | 912 Object* constructor = map()->constructor(); |
891 bool printed = false; | 913 bool printed = false; |
892 if (constructor->IsHeapObject() && | 914 if (constructor->IsHeapObject() && |
893 !Heap::Contains(HeapObject::cast(constructor))) { | 915 !heap->Contains(HeapObject::cast(constructor))) { |
894 accumulator->Add("!!!INVALID CONSTRUCTOR!!!"); | 916 accumulator->Add("!!!INVALID CONSTRUCTOR!!!"); |
895 } else { | 917 } else { |
896 bool global_object = IsJSGlobalProxy(); | 918 bool global_object = IsJSGlobalProxy(); |
897 if (constructor->IsJSFunction()) { | 919 if (constructor->IsJSFunction()) { |
898 if (!Heap::Contains(JSFunction::cast(constructor)->shared())) { | 920 if (!heap->Contains(JSFunction::cast(constructor)->shared())) { |
899 accumulator->Add("!!!INVALID SHARED ON CONSTRUCTOR!!!"); | 921 accumulator->Add("!!!INVALID SHARED ON CONSTRUCTOR!!!"); |
900 } else { | 922 } else { |
901 Object* constructor_name = | 923 Object* constructor_name = |
902 JSFunction::cast(constructor)->shared()->name(); | 924 JSFunction::cast(constructor)->shared()->name(); |
903 if (constructor_name->IsString()) { | 925 if (constructor_name->IsString()) { |
904 String* str = String::cast(constructor_name); | 926 String* str = String::cast(constructor_name); |
905 if (str->length() > 0) { | 927 if (str->length() > 0) { |
906 bool vowel = AnWord(str); | 928 bool vowel = AnWord(str); |
907 accumulator->Add("<%sa%s ", | 929 accumulator->Add("<%sa%s ", |
908 global_object ? "Global Object: " : "", | 930 global_object ? "Global Object: " : "", |
(...skipping 14 matching lines...) Expand all Loading... |
923 JSValue::cast(this)->value()->ShortPrint(accumulator); | 945 JSValue::cast(this)->value()->ShortPrint(accumulator); |
924 } | 946 } |
925 accumulator->Put('>'); | 947 accumulator->Put('>'); |
926 break; | 948 break; |
927 } | 949 } |
928 } | 950 } |
929 } | 951 } |
930 | 952 |
931 | 953 |
932 void HeapObject::HeapObjectShortPrint(StringStream* accumulator) { | 954 void HeapObject::HeapObjectShortPrint(StringStream* accumulator) { |
933 // if (!Heap::InNewSpace(this)) PrintF("*", this); | 955 // if (!HEAP->InNewSpace(this)) PrintF("*", this); |
934 if (!Heap::Contains(this)) { | 956 Heap* heap = GetHeap(); |
| 957 if (!heap->Contains(this)) { |
935 accumulator->Add("!!!INVALID POINTER!!!"); | 958 accumulator->Add("!!!INVALID POINTER!!!"); |
936 return; | 959 return; |
937 } | 960 } |
938 if (!Heap::Contains(map())) { | 961 if (!heap->Contains(map())) { |
939 accumulator->Add("!!!INVALID MAP!!!"); | 962 accumulator->Add("!!!INVALID MAP!!!"); |
940 return; | 963 return; |
941 } | 964 } |
942 | 965 |
943 accumulator->Add("%p ", this); | 966 accumulator->Add("%p ", this); |
944 | 967 |
945 if (IsString()) { | 968 if (IsString()) { |
946 String::cast(this)->StringShortPrint(accumulator); | 969 String::cast(this)->StringShortPrint(accumulator); |
947 return; | 970 return; |
948 } | 971 } |
(...skipping 194 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1143 // NaN, +0, and -0 should return the false object | 1166 // NaN, +0, and -0 should return the false object |
1144 #if __BYTE_ORDER == __LITTLE_ENDIAN | 1167 #if __BYTE_ORDER == __LITTLE_ENDIAN |
1145 union IeeeDoubleLittleEndianArchType u; | 1168 union IeeeDoubleLittleEndianArchType u; |
1146 #elif __BYTE_ORDER == __BIG_ENDIAN | 1169 #elif __BYTE_ORDER == __BIG_ENDIAN |
1147 union IeeeDoubleBigEndianArchType u; | 1170 union IeeeDoubleBigEndianArchType u; |
1148 #endif | 1171 #endif |
1149 u.d = value(); | 1172 u.d = value(); |
1150 if (u.bits.exp == 2047) { | 1173 if (u.bits.exp == 2047) { |
1151 // Detect NaN for IEEE double precision floating point. | 1174 // Detect NaN for IEEE double precision floating point. |
1152 if ((u.bits.man_low | u.bits.man_high) != 0) | 1175 if ((u.bits.man_low | u.bits.man_high) != 0) |
1153 return Heap::false_value(); | 1176 return GetHeap()->false_value(); |
1154 } | 1177 } |
1155 if (u.bits.exp == 0) { | 1178 if (u.bits.exp == 0) { |
1156 // Detect +0, and -0 for IEEE double precision floating point. | 1179 // Detect +0, and -0 for IEEE double precision floating point. |
1157 if ((u.bits.man_low | u.bits.man_high) == 0) | 1180 if ((u.bits.man_low | u.bits.man_high) == 0) |
1158 return Heap::false_value(); | 1181 return GetHeap()->false_value(); |
1159 } | 1182 } |
1160 return Heap::true_value(); | 1183 return GetHeap()->true_value(); |
1161 } | 1184 } |
1162 | 1185 |
1163 | 1186 |
1164 void HeapNumber::HeapNumberPrint(FILE* out) { | 1187 void HeapNumber::HeapNumberPrint(FILE* out) { |
1165 PrintF(out, "%.16g", Number()); | 1188 PrintF(out, "%.16g", Number()); |
1166 } | 1189 } |
1167 | 1190 |
1168 | 1191 |
1169 void HeapNumber::HeapNumberPrint(StringStream* accumulator) { | 1192 void HeapNumber::HeapNumberPrint(StringStream* accumulator) { |
1170 // The Windows version of vsnprintf can allocate when printing a %g string | 1193 // The Windows version of vsnprintf can allocate when printing a %g string |
1171 // into a buffer that may not be big enough. We don't want random memory | 1194 // into a buffer that may not be big enough. We don't want random memory |
1172 // allocation when producing post-crash stack traces, so we print into a | 1195 // allocation when producing post-crash stack traces, so we print into a |
1173 // buffer that is plenty big enough for any floating point number, then | 1196 // buffer that is plenty big enough for any floating point number, then |
1174 // print that using vsnprintf (which may truncate but never allocate if | 1197 // print that using vsnprintf (which may truncate but never allocate if |
1175 // there is no more space in the buffer). | 1198 // there is no more space in the buffer). |
1176 EmbeddedVector<char, 100> buffer; | 1199 EmbeddedVector<char, 100> buffer; |
1177 OS::SNPrintF(buffer, "%.16g", Number()); | 1200 OS::SNPrintF(buffer, "%.16g", Number()); |
1178 accumulator->Add("%s", buffer.start()); | 1201 accumulator->Add("%s", buffer.start()); |
1179 } | 1202 } |
1180 | 1203 |
1181 | 1204 |
1182 String* JSObject::class_name() { | 1205 String* JSObject::class_name() { |
1183 if (IsJSFunction()) { | 1206 if (IsJSFunction()) { |
1184 return Heap::function_class_symbol(); | 1207 return GetHeap()->function_class_symbol(); |
1185 } | 1208 } |
1186 if (map()->constructor()->IsJSFunction()) { | 1209 if (map()->constructor()->IsJSFunction()) { |
1187 JSFunction* constructor = JSFunction::cast(map()->constructor()); | 1210 JSFunction* constructor = JSFunction::cast(map()->constructor()); |
1188 return String::cast(constructor->shared()->instance_class_name()); | 1211 return String::cast(constructor->shared()->instance_class_name()); |
1189 } | 1212 } |
1190 // If the constructor is not present, return "Object". | 1213 // If the constructor is not present, return "Object". |
1191 return Heap::Object_symbol(); | 1214 return GetHeap()->Object_symbol(); |
1192 } | 1215 } |
1193 | 1216 |
1194 | 1217 |
1195 String* JSObject::constructor_name() { | 1218 String* JSObject::constructor_name() { |
1196 if (map()->constructor()->IsJSFunction()) { | 1219 if (map()->constructor()->IsJSFunction()) { |
1197 JSFunction* constructor = JSFunction::cast(map()->constructor()); | 1220 JSFunction* constructor = JSFunction::cast(map()->constructor()); |
1198 String* name = String::cast(constructor->shared()->name()); | 1221 String* name = String::cast(constructor->shared()->name()); |
1199 if (name->length() > 0) return name; | 1222 if (name->length() > 0) return name; |
1200 String* inferred_name = constructor->shared()->inferred_name(); | 1223 String* inferred_name = constructor->shared()->inferred_name(); |
1201 if (inferred_name->length() > 0) return inferred_name; | 1224 if (inferred_name->length() > 0) return inferred_name; |
1202 Object* proto = GetPrototype(); | 1225 Object* proto = GetPrototype(); |
1203 if (proto->IsJSObject()) return JSObject::cast(proto)->constructor_name(); | 1226 if (proto->IsJSObject()) return JSObject::cast(proto)->constructor_name(); |
1204 } | 1227 } |
1205 // If the constructor is not present, return "Object". | 1228 // If the constructor is not present, return "Object". |
1206 return Heap::Object_symbol(); | 1229 return GetHeap()->Object_symbol(); |
1207 } | 1230 } |
1208 | 1231 |
1209 | 1232 |
1210 MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map, | 1233 MaybeObject* JSObject::AddFastPropertyUsingMap(Map* new_map, |
1211 String* name, | 1234 String* name, |
1212 Object* value) { | 1235 Object* value) { |
1213 int index = new_map->PropertyIndexFor(name); | 1236 int index = new_map->PropertyIndexFor(name); |
1214 if (map()->unused_property_fields() == 0) { | 1237 if (map()->unused_property_fields() == 0) { |
1215 ASSERT(map()->unused_property_fields() == 0); | 1238 ASSERT(map()->unused_property_fields() == 0); |
1216 int new_unused = new_map->unused_property_fields(); | 1239 int new_unused = new_map->unused_property_fields(); |
1217 Object* values; | 1240 Object* values; |
1218 { MaybeObject* maybe_values = | 1241 { MaybeObject* maybe_values = |
1219 properties()->CopySize(properties()->length() + new_unused + 1); | 1242 properties()->CopySize(properties()->length() + new_unused + 1); |
1220 if (!maybe_values->ToObject(&values)) return maybe_values; | 1243 if (!maybe_values->ToObject(&values)) return maybe_values; |
1221 } | 1244 } |
1222 set_properties(FixedArray::cast(values)); | 1245 set_properties(FixedArray::cast(values)); |
1223 } | 1246 } |
1224 set_map(new_map); | 1247 set_map(new_map); |
1225 return FastPropertyAtPut(index, value); | 1248 return FastPropertyAtPut(index, value); |
1226 } | 1249 } |
1227 | 1250 |
1228 | 1251 |
1229 MaybeObject* JSObject::AddFastProperty(String* name, | 1252 MaybeObject* JSObject::AddFastProperty(String* name, |
1230 Object* value, | 1253 Object* value, |
1231 PropertyAttributes attributes) { | 1254 PropertyAttributes attributes) { |
1232 ASSERT(!IsJSGlobalProxy()); | 1255 ASSERT(!IsJSGlobalProxy()); |
1233 | 1256 |
1234 // Normalize the object if the name is an actual string (not the | 1257 // Normalize the object if the name is an actual string (not the |
1235 // hidden symbols) and is not a real identifier. | 1258 // hidden symbols) and is not a real identifier. |
| 1259 Isolate* isolate = GetHeap()->isolate(); |
1236 StringInputBuffer buffer(name); | 1260 StringInputBuffer buffer(name); |
1237 if (!ScannerConstants::IsIdentifier(&buffer) | 1261 if (!isolate->scanner_constants()->IsIdentifier(&buffer) |
1238 && name != Heap::hidden_symbol()) { | 1262 && name != HEAP->hidden_symbol()) { |
1239 Object* obj; | 1263 Object* obj; |
1240 { MaybeObject* maybe_obj = | 1264 { MaybeObject* maybe_obj = |
1241 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 1265 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
1242 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 1266 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
1243 } | 1267 } |
1244 return AddSlowProperty(name, value, attributes); | 1268 return AddSlowProperty(name, value, attributes); |
1245 } | 1269 } |
1246 | 1270 |
1247 DescriptorArray* old_descriptors = map()->instance_descriptors(); | 1271 DescriptorArray* old_descriptors = map()->instance_descriptors(); |
1248 // Compute the new index for new field. | 1272 // Compute the new index for new field. |
1249 int index = map()->NextFreePropertyIndex(); | 1273 int index = map()->NextFreePropertyIndex(); |
1250 | 1274 |
1251 // Allocate new instance descriptors with (name, index) added | 1275 // Allocate new instance descriptors with (name, index) added |
1252 FieldDescriptor new_field(name, index, attributes); | 1276 FieldDescriptor new_field(name, index, attributes); |
1253 Object* new_descriptors; | 1277 Object* new_descriptors; |
1254 { MaybeObject* maybe_new_descriptors = | 1278 { MaybeObject* maybe_new_descriptors = |
1255 old_descriptors->CopyInsert(&new_field, REMOVE_TRANSITIONS); | 1279 old_descriptors->CopyInsert(&new_field, REMOVE_TRANSITIONS); |
1256 if (!maybe_new_descriptors->ToObject(&new_descriptors)) { | 1280 if (!maybe_new_descriptors->ToObject(&new_descriptors)) { |
1257 return maybe_new_descriptors; | 1281 return maybe_new_descriptors; |
1258 } | 1282 } |
1259 } | 1283 } |
1260 | 1284 |
1261 // Only allow map transition if the object's map is NOT equal to the | 1285 // Only allow map transition if the object's map is NOT equal to the |
1262 // global object_function's map and there is not a transition for name. | 1286 // global object_function's map and there is not a transition for name. |
1263 bool allow_map_transition = | 1287 bool allow_map_transition = |
1264 !old_descriptors->Contains(name) && | 1288 !old_descriptors->Contains(name) && |
1265 (Top::context()->global_context()->object_function()->map() != map()); | 1289 (isolate->context()->global_context()->object_function()-> |
| 1290 map() != map()); |
1266 | 1291 |
1267 ASSERT(index < map()->inobject_properties() || | 1292 ASSERT(index < map()->inobject_properties() || |
1268 (index - map()->inobject_properties()) < properties()->length() || | 1293 (index - map()->inobject_properties()) < properties()->length() || |
1269 map()->unused_property_fields() == 0); | 1294 map()->unused_property_fields() == 0); |
1270 // Allocate a new map for the object. | 1295 // Allocate a new map for the object. |
1271 Object* r; | 1296 Object* r; |
1272 { MaybeObject* maybe_r = map()->CopyDropDescriptors(); | 1297 { MaybeObject* maybe_r = map()->CopyDropDescriptors(); |
1273 if (!maybe_r->ToObject(&r)) return maybe_r; | 1298 if (!maybe_r->ToObject(&r)) return maybe_r; |
1274 } | 1299 } |
1275 Map* new_map = Map::cast(r); | 1300 Map* new_map = Map::cast(r); |
(...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1309 new_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors)); | 1334 new_map->set_instance_descriptors(DescriptorArray::cast(new_descriptors)); |
1310 set_map(new_map); | 1335 set_map(new_map); |
1311 return FastPropertyAtPut(index, value); | 1336 return FastPropertyAtPut(index, value); |
1312 } | 1337 } |
1313 | 1338 |
1314 | 1339 |
1315 MaybeObject* JSObject::AddConstantFunctionProperty( | 1340 MaybeObject* JSObject::AddConstantFunctionProperty( |
1316 String* name, | 1341 String* name, |
1317 JSFunction* function, | 1342 JSFunction* function, |
1318 PropertyAttributes attributes) { | 1343 PropertyAttributes attributes) { |
1319 ASSERT(!Heap::InNewSpace(function)); | 1344 Heap* heap = GetHeap(); |
| 1345 ASSERT(!heap->InNewSpace(function)); |
1320 | 1346 |
1321 // Allocate new instance descriptors with (name, function) added | 1347 // Allocate new instance descriptors with (name, function) added |
1322 ConstantFunctionDescriptor d(name, function, attributes); | 1348 ConstantFunctionDescriptor d(name, function, attributes); |
1323 Object* new_descriptors; | 1349 Object* new_descriptors; |
1324 { MaybeObject* maybe_new_descriptors = | 1350 { MaybeObject* maybe_new_descriptors = |
1325 map()->instance_descriptors()->CopyInsert(&d, REMOVE_TRANSITIONS); | 1351 map()->instance_descriptors()->CopyInsert(&d, REMOVE_TRANSITIONS); |
1326 if (!maybe_new_descriptors->ToObject(&new_descriptors)) { | 1352 if (!maybe_new_descriptors->ToObject(&new_descriptors)) { |
1327 return maybe_new_descriptors; | 1353 return maybe_new_descriptors; |
1328 } | 1354 } |
1329 } | 1355 } |
1330 | 1356 |
1331 // Allocate a new map for the object. | 1357 // Allocate a new map for the object. |
1332 Object* new_map; | 1358 Object* new_map; |
1333 { MaybeObject* maybe_new_map = map()->CopyDropDescriptors(); | 1359 { MaybeObject* maybe_new_map = map()->CopyDropDescriptors(); |
1334 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; | 1360 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; |
1335 } | 1361 } |
1336 | 1362 |
1337 DescriptorArray* descriptors = DescriptorArray::cast(new_descriptors); | 1363 DescriptorArray* descriptors = DescriptorArray::cast(new_descriptors); |
1338 Map::cast(new_map)->set_instance_descriptors(descriptors); | 1364 Map::cast(new_map)->set_instance_descriptors(descriptors); |
1339 Map* old_map = map(); | 1365 Map* old_map = map(); |
1340 set_map(Map::cast(new_map)); | 1366 set_map(Map::cast(new_map)); |
1341 | 1367 |
1342 // If the old map is the global object map (from new Object()), | 1368 // If the old map is the global object map (from new Object()), |
1343 // then transitions are not added to it, so we are done. | 1369 // then transitions are not added to it, so we are done. |
1344 if (old_map == Top::context()->global_context()->object_function()->map()) { | 1370 if (old_map == heap->isolate()->context()->global_context()-> |
| 1371 object_function()->map()) { |
1345 return function; | 1372 return function; |
1346 } | 1373 } |
1347 | 1374 |
1348 // Do not add CONSTANT_TRANSITIONS to global objects | 1375 // Do not add CONSTANT_TRANSITIONS to global objects |
1349 if (IsGlobalObject()) { | 1376 if (IsGlobalObject()) { |
1350 return function; | 1377 return function; |
1351 } | 1378 } |
1352 | 1379 |
1353 // Add a CONSTANT_TRANSITION descriptor to the old map, | 1380 // Add a CONSTANT_TRANSITION descriptor to the old map, |
1354 // so future assignments to this property on other objects | 1381 // so future assignments to this property on other objects |
(...skipping 14 matching lines...) Expand all Loading... |
1369 | 1396 |
1370 return function; | 1397 return function; |
1371 } | 1398 } |
1372 | 1399 |
1373 | 1400 |
1374 // Add property in slow mode | 1401 // Add property in slow mode |
1375 MaybeObject* JSObject::AddSlowProperty(String* name, | 1402 MaybeObject* JSObject::AddSlowProperty(String* name, |
1376 Object* value, | 1403 Object* value, |
1377 PropertyAttributes attributes) { | 1404 PropertyAttributes attributes) { |
1378 ASSERT(!HasFastProperties()); | 1405 ASSERT(!HasFastProperties()); |
| 1406 Heap* heap = GetHeap(); |
1379 StringDictionary* dict = property_dictionary(); | 1407 StringDictionary* dict = property_dictionary(); |
1380 Object* store_value = value; | 1408 Object* store_value = value; |
1381 if (IsGlobalObject()) { | 1409 if (IsGlobalObject()) { |
1382 // In case name is an orphaned property reuse the cell. | 1410 // In case name is an orphaned property reuse the cell. |
1383 int entry = dict->FindEntry(name); | 1411 int entry = dict->FindEntry(name); |
1384 if (entry != StringDictionary::kNotFound) { | 1412 if (entry != StringDictionary::kNotFound) { |
1385 store_value = dict->ValueAt(entry); | 1413 store_value = dict->ValueAt(entry); |
1386 JSGlobalPropertyCell::cast(store_value)->set_value(value); | 1414 JSGlobalPropertyCell::cast(store_value)->set_value(value); |
1387 // Assign an enumeration index to the property and update | 1415 // Assign an enumeration index to the property and update |
1388 // SetNextEnumerationIndex. | 1416 // SetNextEnumerationIndex. |
1389 int index = dict->NextEnumerationIndex(); | 1417 int index = dict->NextEnumerationIndex(); |
1390 PropertyDetails details = PropertyDetails(attributes, NORMAL, index); | 1418 PropertyDetails details = PropertyDetails(attributes, NORMAL, index); |
1391 dict->SetNextEnumerationIndex(index + 1); | 1419 dict->SetNextEnumerationIndex(index + 1); |
1392 dict->SetEntry(entry, name, store_value, details); | 1420 dict->SetEntry(entry, name, store_value, details); |
1393 return value; | 1421 return value; |
1394 } | 1422 } |
1395 { MaybeObject* maybe_store_value = | 1423 { MaybeObject* maybe_store_value = |
1396 Heap::AllocateJSGlobalPropertyCell(value); | 1424 heap->AllocateJSGlobalPropertyCell(value); |
1397 if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value; | 1425 if (!maybe_store_value->ToObject(&store_value)) return maybe_store_value; |
1398 } | 1426 } |
1399 JSGlobalPropertyCell::cast(store_value)->set_value(value); | 1427 JSGlobalPropertyCell::cast(store_value)->set_value(value); |
1400 } | 1428 } |
1401 PropertyDetails details = PropertyDetails(attributes, NORMAL); | 1429 PropertyDetails details = PropertyDetails(attributes, NORMAL); |
1402 Object* result; | 1430 Object* result; |
1403 { MaybeObject* maybe_result = dict->Add(name, store_value, details); | 1431 { MaybeObject* maybe_result = dict->Add(name, store_value, details); |
1404 if (!maybe_result->ToObject(&result)) return maybe_result; | 1432 if (!maybe_result->ToObject(&result)) return maybe_result; |
1405 } | 1433 } |
1406 if (dict != result) set_properties(StringDictionary::cast(result)); | 1434 if (dict != result) set_properties(StringDictionary::cast(result)); |
1407 return value; | 1435 return value; |
1408 } | 1436 } |
1409 | 1437 |
1410 | 1438 |
1411 MaybeObject* JSObject::AddProperty(String* name, | 1439 MaybeObject* JSObject::AddProperty(String* name, |
1412 Object* value, | 1440 Object* value, |
1413 PropertyAttributes attributes) { | 1441 PropertyAttributes attributes) { |
1414 ASSERT(!IsJSGlobalProxy()); | 1442 ASSERT(!IsJSGlobalProxy()); |
| 1443 Heap* heap = GetHeap(); |
1415 if (!map()->is_extensible()) { | 1444 if (!map()->is_extensible()) { |
1416 Handle<Object> args[1] = {Handle<String>(name)}; | 1445 Handle<Object> args[1] = {Handle<String>(name)}; |
1417 return Top::Throw(*Factory::NewTypeError("object_not_extensible", | 1446 return heap->isolate()->Throw( |
1418 HandleVector(args, 1))); | 1447 *FACTORY->NewTypeError("object_not_extensible", HandleVector(args, 1))); |
1419 } | 1448 } |
1420 if (HasFastProperties()) { | 1449 if (HasFastProperties()) { |
1421 // Ensure the descriptor array does not get too big. | 1450 // Ensure the descriptor array does not get too big. |
1422 if (map()->instance_descriptors()->number_of_descriptors() < | 1451 if (map()->instance_descriptors()->number_of_descriptors() < |
1423 DescriptorArray::kMaxNumberOfDescriptors) { | 1452 DescriptorArray::kMaxNumberOfDescriptors) { |
1424 if (value->IsJSFunction() && !Heap::InNewSpace(value)) { | 1453 if (value->IsJSFunction() && !heap->InNewSpace(value)) { |
1425 return AddConstantFunctionProperty(name, | 1454 return AddConstantFunctionProperty(name, |
1426 JSFunction::cast(value), | 1455 JSFunction::cast(value), |
1427 attributes); | 1456 attributes); |
1428 } else { | 1457 } else { |
1429 return AddFastProperty(name, value, attributes); | 1458 return AddFastProperty(name, value, attributes); |
1430 } | 1459 } |
1431 } else { | 1460 } else { |
1432 // Normalize the object to prevent very large instance descriptors. | 1461 // Normalize the object to prevent very large instance descriptors. |
1433 // This eliminates unwanted N^2 allocation and lookup behavior. | 1462 // This eliminates unwanted N^2 allocation and lookup behavior. |
1434 Object* obj; | 1463 Object* obj; |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1486 { MaybeObject* maybe_result = | 1515 { MaybeObject* maybe_result = |
1487 ConvertDescriptorToField(name, new_value, attributes); | 1516 ConvertDescriptorToField(name, new_value, attributes); |
1488 if (!maybe_result->ToObject(&result)) return maybe_result; | 1517 if (!maybe_result->ToObject(&result)) return maybe_result; |
1489 } | 1518 } |
1490 // If we get to this point we have succeeded - do not return failure | 1519 // If we get to this point we have succeeded - do not return failure |
1491 // after this point. Later stuff is optional. | 1520 // after this point. Later stuff is optional. |
1492 if (!HasFastProperties()) { | 1521 if (!HasFastProperties()) { |
1493 return result; | 1522 return result; |
1494 } | 1523 } |
1495 // Do not add transitions to the map of "new Object()". | 1524 // Do not add transitions to the map of "new Object()". |
1496 if (map() == Top::context()->global_context()->object_function()->map()) { | 1525 if (map() == GetHeap()->isolate()->context()->global_context()-> |
| 1526 object_function()->map()) { |
1497 return result; | 1527 return result; |
1498 } | 1528 } |
1499 | 1529 |
1500 MapTransitionDescriptor transition(name, | 1530 MapTransitionDescriptor transition(name, |
1501 map(), | 1531 map(), |
1502 attributes); | 1532 attributes); |
1503 Object* new_descriptors; | 1533 Object* new_descriptors; |
1504 { MaybeObject* maybe_new_descriptors = old_map->instance_descriptors()-> | 1534 { MaybeObject* maybe_new_descriptors = old_map->instance_descriptors()-> |
1505 CopyInsert(&transition, KEEP_TRANSITIONS); | 1535 CopyInsert(&transition, KEEP_TRANSITIONS); |
1506 if (!maybe_new_descriptors->ToObject(&new_descriptors)) { | 1536 if (!maybe_new_descriptors->ToObject(&new_descriptors)) { |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1573 return FastPropertyAtPut(index, new_value); | 1603 return FastPropertyAtPut(index, new_value); |
1574 } | 1604 } |
1575 | 1605 |
1576 | 1606 |
1577 | 1607 |
1578 MaybeObject* JSObject::SetPropertyWithInterceptor( | 1608 MaybeObject* JSObject::SetPropertyWithInterceptor( |
1579 String* name, | 1609 String* name, |
1580 Object* value, | 1610 Object* value, |
1581 PropertyAttributes attributes, | 1611 PropertyAttributes attributes, |
1582 StrictModeFlag strict_mode) { | 1612 StrictModeFlag strict_mode) { |
1583 HandleScope scope; | 1613 Isolate* isolate = GetIsolate(); |
| 1614 HandleScope scope(isolate); |
1584 Handle<JSObject> this_handle(this); | 1615 Handle<JSObject> this_handle(this); |
1585 Handle<String> name_handle(name); | 1616 Handle<String> name_handle(name); |
1586 Handle<Object> value_handle(value); | 1617 Handle<Object> value_handle(value, isolate); |
1587 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); | 1618 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); |
1588 if (!interceptor->setter()->IsUndefined()) { | 1619 if (!interceptor->setter()->IsUndefined()) { |
1589 LOG(ApiNamedPropertyAccess("interceptor-named-set", this, name)); | 1620 LOG(isolate, ApiNamedPropertyAccess("interceptor-named-set", this, name)); |
1590 CustomArguments args(interceptor->data(), this, this); | 1621 CustomArguments args(isolate, interceptor->data(), this, this); |
1591 v8::AccessorInfo info(args.end()); | 1622 v8::AccessorInfo info(args.end()); |
1592 v8::NamedPropertySetter setter = | 1623 v8::NamedPropertySetter setter = |
1593 v8::ToCData<v8::NamedPropertySetter>(interceptor->setter()); | 1624 v8::ToCData<v8::NamedPropertySetter>(interceptor->setter()); |
1594 v8::Handle<v8::Value> result; | 1625 v8::Handle<v8::Value> result; |
1595 { | 1626 { |
1596 // Leaving JavaScript. | 1627 // Leaving JavaScript. |
1597 VMState state(EXTERNAL); | 1628 VMState state(isolate, EXTERNAL); |
1598 Handle<Object> value_unhole(value->IsTheHole() ? | 1629 Handle<Object> value_unhole(value->IsTheHole() ? |
1599 Heap::undefined_value() : | 1630 isolate->heap()->undefined_value() : |
1600 value); | 1631 value, |
| 1632 isolate); |
1601 result = setter(v8::Utils::ToLocal(name_handle), | 1633 result = setter(v8::Utils::ToLocal(name_handle), |
1602 v8::Utils::ToLocal(value_unhole), | 1634 v8::Utils::ToLocal(value_unhole), |
1603 info); | 1635 info); |
1604 } | 1636 } |
1605 RETURN_IF_SCHEDULED_EXCEPTION(); | 1637 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
1606 if (!result.IsEmpty()) return *value_handle; | 1638 if (!result.IsEmpty()) return *value_handle; |
1607 } | 1639 } |
1608 MaybeObject* raw_result = | 1640 MaybeObject* raw_result = |
1609 this_handle->SetPropertyPostInterceptor(*name_handle, | 1641 this_handle->SetPropertyPostInterceptor(*name_handle, |
1610 *value_handle, | 1642 *value_handle, |
1611 attributes, | 1643 attributes, |
1612 strict_mode); | 1644 strict_mode); |
1613 RETURN_IF_SCHEDULED_EXCEPTION(); | 1645 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
1614 return raw_result; | 1646 return raw_result; |
1615 } | 1647 } |
1616 | 1648 |
1617 | 1649 |
1618 MaybeObject* JSObject::SetProperty(String* name, | 1650 MaybeObject* JSObject::SetProperty(String* name, |
1619 Object* value, | 1651 Object* value, |
1620 PropertyAttributes attributes, | 1652 PropertyAttributes attributes, |
1621 StrictModeFlag strict_mode) { | 1653 StrictModeFlag strict_mode) { |
1622 LookupResult result; | 1654 LookupResult result; |
1623 LocalLookup(name, &result); | 1655 LocalLookup(name, &result); |
1624 return SetProperty(&result, name, value, attributes, strict_mode); | 1656 return SetProperty(&result, name, value, attributes, strict_mode); |
1625 } | 1657 } |
1626 | 1658 |
1627 | 1659 |
1628 MaybeObject* JSObject::SetPropertyWithCallback(Object* structure, | 1660 MaybeObject* JSObject::SetPropertyWithCallback(Object* structure, |
1629 String* name, | 1661 String* name, |
1630 Object* value, | 1662 Object* value, |
1631 JSObject* holder) { | 1663 JSObject* holder) { |
1632 HandleScope scope; | 1664 Isolate* isolate = GetIsolate(); |
| 1665 HandleScope scope(isolate); |
1633 | 1666 |
1634 // We should never get here to initialize a const with the hole | 1667 // We should never get here to initialize a const with the hole |
1635 // value since a const declaration would conflict with the setter. | 1668 // value since a const declaration would conflict with the setter. |
1636 ASSERT(!value->IsTheHole()); | 1669 ASSERT(!value->IsTheHole()); |
1637 Handle<Object> value_handle(value); | 1670 Handle<Object> value_handle(value, isolate); |
1638 | 1671 |
1639 // To accommodate both the old and the new api we switch on the | 1672 // To accommodate both the old and the new api we switch on the |
1640 // data structure used to store the callbacks. Eventually proxy | 1673 // data structure used to store the callbacks. Eventually proxy |
1641 // callbacks should be phased out. | 1674 // callbacks should be phased out. |
1642 if (structure->IsProxy()) { | 1675 if (structure->IsProxy()) { |
1643 AccessorDescriptor* callback = | 1676 AccessorDescriptor* callback = |
1644 reinterpret_cast<AccessorDescriptor*>(Proxy::cast(structure)->proxy()); | 1677 reinterpret_cast<AccessorDescriptor*>(Proxy::cast(structure)->proxy()); |
1645 MaybeObject* obj = (callback->setter)(this, value, callback->data); | 1678 MaybeObject* obj = (callback->setter)(this, value, callback->data); |
1646 RETURN_IF_SCHEDULED_EXCEPTION(); | 1679 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
1647 if (obj->IsFailure()) return obj; | 1680 if (obj->IsFailure()) return obj; |
1648 return *value_handle; | 1681 return *value_handle; |
1649 } | 1682 } |
1650 | 1683 |
1651 if (structure->IsAccessorInfo()) { | 1684 if (structure->IsAccessorInfo()) { |
1652 // api style callbacks | 1685 // api style callbacks |
1653 AccessorInfo* data = AccessorInfo::cast(structure); | 1686 AccessorInfo* data = AccessorInfo::cast(structure); |
1654 Object* call_obj = data->setter(); | 1687 Object* call_obj = data->setter(); |
1655 v8::AccessorSetter call_fun = v8::ToCData<v8::AccessorSetter>(call_obj); | 1688 v8::AccessorSetter call_fun = v8::ToCData<v8::AccessorSetter>(call_obj); |
1656 if (call_fun == NULL) return value; | 1689 if (call_fun == NULL) return value; |
1657 Handle<String> key(name); | 1690 Handle<String> key(name); |
1658 LOG(ApiNamedPropertyAccess("store", this, name)); | 1691 LOG(isolate, ApiNamedPropertyAccess("store", this, name)); |
1659 CustomArguments args(data->data(), this, JSObject::cast(holder)); | 1692 CustomArguments args(isolate, data->data(), this, JSObject::cast(holder)); |
1660 v8::AccessorInfo info(args.end()); | 1693 v8::AccessorInfo info(args.end()); |
1661 { | 1694 { |
1662 // Leaving JavaScript. | 1695 // Leaving JavaScript. |
1663 VMState state(EXTERNAL); | 1696 VMState state(isolate, EXTERNAL); |
1664 call_fun(v8::Utils::ToLocal(key), | 1697 call_fun(v8::Utils::ToLocal(key), |
1665 v8::Utils::ToLocal(value_handle), | 1698 v8::Utils::ToLocal(value_handle), |
1666 info); | 1699 info); |
1667 } | 1700 } |
1668 RETURN_IF_SCHEDULED_EXCEPTION(); | 1701 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
1669 return *value_handle; | 1702 return *value_handle; |
1670 } | 1703 } |
1671 | 1704 |
1672 if (structure->IsFixedArray()) { | 1705 if (structure->IsFixedArray()) { |
1673 Object* setter = FixedArray::cast(structure)->get(kSetterIndex); | 1706 Object* setter = FixedArray::cast(structure)->get(kSetterIndex); |
1674 if (setter->IsJSFunction()) { | 1707 if (setter->IsJSFunction()) { |
1675 return SetPropertyWithDefinedSetter(JSFunction::cast(setter), value); | 1708 return SetPropertyWithDefinedSetter(JSFunction::cast(setter), value); |
1676 } else { | 1709 } else { |
1677 Handle<String> key(name); | 1710 Handle<String> key(name); |
1678 Handle<Object> holder_handle(holder); | 1711 Handle<Object> holder_handle(holder, isolate); |
1679 Handle<Object> args[2] = { key, holder_handle }; | 1712 Handle<Object> args[2] = { key, holder_handle }; |
1680 return Top::Throw(*Factory::NewTypeError("no_setter_in_callback", | 1713 return isolate->Throw( |
1681 HandleVector(args, 2))); | 1714 *isolate->factory()->NewTypeError("no_setter_in_callback", |
| 1715 HandleVector(args, 2))); |
1682 } | 1716 } |
1683 } | 1717 } |
1684 | 1718 |
1685 UNREACHABLE(); | 1719 UNREACHABLE(); |
1686 return NULL; | 1720 return NULL; |
1687 } | 1721 } |
1688 | 1722 |
1689 | 1723 |
1690 MaybeObject* JSObject::SetPropertyWithDefinedSetter(JSFunction* setter, | 1724 MaybeObject* JSObject::SetPropertyWithDefinedSetter(JSFunction* setter, |
1691 Object* value) { | 1725 Object* value) { |
1692 Handle<Object> value_handle(value); | 1726 Isolate* isolate = GetIsolate(); |
1693 Handle<JSFunction> fun(JSFunction::cast(setter)); | 1727 Handle<Object> value_handle(value, isolate); |
1694 Handle<JSObject> self(this); | 1728 Handle<JSFunction> fun(JSFunction::cast(setter), isolate); |
| 1729 Handle<JSObject> self(this, isolate); |
1695 #ifdef ENABLE_DEBUGGER_SUPPORT | 1730 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 1731 Debug* debug = isolate->debug(); |
1696 // Handle stepping into a setter if step into is active. | 1732 // Handle stepping into a setter if step into is active. |
1697 if (Debug::StepInActive()) { | 1733 if (debug->StepInActive()) { |
1698 Debug::HandleStepIn(fun, Handle<Object>::null(), 0, false); | 1734 debug->HandleStepIn(fun, Handle<Object>::null(), 0, false); |
1699 } | 1735 } |
1700 #endif | 1736 #endif |
1701 bool has_pending_exception; | 1737 bool has_pending_exception; |
1702 Object** argv[] = { value_handle.location() }; | 1738 Object** argv[] = { value_handle.location() }; |
1703 Execution::Call(fun, self, 1, argv, &has_pending_exception); | 1739 Execution::Call(fun, self, 1, argv, &has_pending_exception); |
1704 // Check for pending exception and return the result. | 1740 // Check for pending exception and return the result. |
1705 if (has_pending_exception) return Failure::Exception(); | 1741 if (has_pending_exception) return Failure::Exception(); |
1706 return *value_handle; | 1742 return *value_handle; |
1707 } | 1743 } |
1708 | 1744 |
1709 | 1745 |
1710 void JSObject::LookupCallbackSetterInPrototypes(String* name, | 1746 void JSObject::LookupCallbackSetterInPrototypes(String* name, |
1711 LookupResult* result) { | 1747 LookupResult* result) { |
| 1748 Heap* heap = GetHeap(); |
1712 for (Object* pt = GetPrototype(); | 1749 for (Object* pt = GetPrototype(); |
1713 pt != Heap::null_value(); | 1750 pt != heap->null_value(); |
1714 pt = pt->GetPrototype()) { | 1751 pt = pt->GetPrototype()) { |
1715 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); | 1752 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); |
1716 if (result->IsProperty()) { | 1753 if (result->IsProperty()) { |
1717 if (result->IsReadOnly()) { | 1754 if (result->IsReadOnly()) { |
1718 result->NotFound(); | 1755 result->NotFound(); |
1719 return; | 1756 return; |
1720 } | 1757 } |
1721 if (result->type() == CALLBACKS) { | 1758 if (result->type() == CALLBACKS) { |
1722 return; | 1759 return; |
1723 } | 1760 } |
1724 } | 1761 } |
1725 } | 1762 } |
1726 result->NotFound(); | 1763 result->NotFound(); |
1727 } | 1764 } |
1728 | 1765 |
1729 | 1766 |
1730 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes(uint32_t index, | 1767 MaybeObject* JSObject::SetElementWithCallbackSetterInPrototypes(uint32_t index, |
1731 Object* value, | 1768 Object* value, |
1732 bool* found) { | 1769 bool* found) { |
| 1770 Heap* heap = GetHeap(); |
1733 for (Object* pt = GetPrototype(); | 1771 for (Object* pt = GetPrototype(); |
1734 pt != Heap::null_value(); | 1772 pt != heap->null_value(); |
1735 pt = pt->GetPrototype()) { | 1773 pt = pt->GetPrototype()) { |
1736 if (!JSObject::cast(pt)->HasDictionaryElements()) { | 1774 if (!JSObject::cast(pt)->HasDictionaryElements()) { |
1737 continue; | 1775 continue; |
1738 } | 1776 } |
1739 NumberDictionary* dictionary = JSObject::cast(pt)->element_dictionary(); | 1777 NumberDictionary* dictionary = JSObject::cast(pt)->element_dictionary(); |
1740 int entry = dictionary->FindEntry(index); | 1778 int entry = dictionary->FindEntry(index); |
1741 if (entry != NumberDictionary::kNotFound) { | 1779 if (entry != NumberDictionary::kNotFound) { |
1742 PropertyDetails details = dictionary->DetailsAt(entry); | 1780 PropertyDetails details = dictionary->DetailsAt(entry); |
1743 if (details.type() == CALLBACKS) { | 1781 if (details.type() == CALLBACKS) { |
1744 *found = true; | 1782 *found = true; |
1745 return SetElementWithCallback( | 1783 return SetElementWithCallback( |
1746 dictionary->ValueAt(entry), index, value, JSObject::cast(pt)); | 1784 dictionary->ValueAt(entry), index, value, JSObject::cast(pt)); |
1747 } | 1785 } |
1748 } | 1786 } |
1749 } | 1787 } |
1750 *found = false; | 1788 *found = false; |
1751 return Heap::the_hole_value(); | 1789 return heap->the_hole_value(); |
1752 } | 1790 } |
1753 | 1791 |
1754 | 1792 |
1755 void JSObject::LookupInDescriptor(String* name, LookupResult* result) { | 1793 void JSObject::LookupInDescriptor(String* name, LookupResult* result) { |
1756 DescriptorArray* descriptors = map()->instance_descriptors(); | 1794 DescriptorArray* descriptors = map()->instance_descriptors(); |
1757 int number = descriptors->SearchWithCache(name); | 1795 int number = descriptors->SearchWithCache(name); |
1758 if (number != DescriptorArray::kNotFound) { | 1796 if (number != DescriptorArray::kNotFound) { |
1759 result->DescriptorResult(this, descriptors->GetDetails(number), number); | 1797 result->DescriptorResult(this, descriptors->GetDetails(number), number); |
1760 } else { | 1798 } else { |
1761 result->NotFound(); | 1799 result->NotFound(); |
1762 } | 1800 } |
1763 } | 1801 } |
1764 | 1802 |
1765 | 1803 |
1766 void Map::LookupInDescriptors(JSObject* holder, | 1804 void Map::LookupInDescriptors(JSObject* holder, |
1767 String* name, | 1805 String* name, |
1768 LookupResult* result) { | 1806 LookupResult* result) { |
1769 DescriptorArray* descriptors = instance_descriptors(); | 1807 DescriptorArray* descriptors = instance_descriptors(); |
1770 int number = DescriptorLookupCache::Lookup(descriptors, name); | 1808 DescriptorLookupCache* cache = heap()->isolate()->descriptor_lookup_cache(); |
| 1809 int number = cache->Lookup(descriptors, name); |
1771 if (number == DescriptorLookupCache::kAbsent) { | 1810 if (number == DescriptorLookupCache::kAbsent) { |
1772 number = descriptors->Search(name); | 1811 number = descriptors->Search(name); |
1773 DescriptorLookupCache::Update(descriptors, name, number); | 1812 cache->Update(descriptors, name, number); |
1774 } | 1813 } |
1775 if (number != DescriptorArray::kNotFound) { | 1814 if (number != DescriptorArray::kNotFound) { |
1776 result->DescriptorResult(holder, descriptors->GetDetails(number), number); | 1815 result->DescriptorResult(holder, descriptors->GetDetails(number), number); |
1777 } else { | 1816 } else { |
1778 result->NotFound(); | 1817 result->NotFound(); |
1779 } | 1818 } |
1780 } | 1819 } |
1781 | 1820 |
1782 | 1821 |
1783 void JSObject::LocalLookupRealNamedProperty(String* name, | 1822 void JSObject::LocalLookupRealNamedProperty(String* name, |
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1831 void JSObject::LookupRealNamedProperty(String* name, LookupResult* result) { | 1870 void JSObject::LookupRealNamedProperty(String* name, LookupResult* result) { |
1832 LocalLookupRealNamedProperty(name, result); | 1871 LocalLookupRealNamedProperty(name, result); |
1833 if (result->IsProperty()) return; | 1872 if (result->IsProperty()) return; |
1834 | 1873 |
1835 LookupRealNamedPropertyInPrototypes(name, result); | 1874 LookupRealNamedPropertyInPrototypes(name, result); |
1836 } | 1875 } |
1837 | 1876 |
1838 | 1877 |
1839 void JSObject::LookupRealNamedPropertyInPrototypes(String* name, | 1878 void JSObject::LookupRealNamedPropertyInPrototypes(String* name, |
1840 LookupResult* result) { | 1879 LookupResult* result) { |
| 1880 Heap* heap = GetHeap(); |
1841 for (Object* pt = GetPrototype(); | 1881 for (Object* pt = GetPrototype(); |
1842 pt != Heap::null_value(); | 1882 pt != heap->null_value(); |
1843 pt = JSObject::cast(pt)->GetPrototype()) { | 1883 pt = JSObject::cast(pt)->GetPrototype()) { |
1844 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); | 1884 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); |
1845 if (result->IsProperty() && (result->type() != INTERCEPTOR)) return; | 1885 if (result->IsProperty() && (result->type() != INTERCEPTOR)) return; |
1846 } | 1886 } |
1847 result->NotFound(); | 1887 result->NotFound(); |
1848 } | 1888 } |
1849 | 1889 |
1850 | 1890 |
1851 // We only need to deal with CALLBACKS and INTERCEPTORS | 1891 // We only need to deal with CALLBACKS and INTERCEPTORS |
1852 MaybeObject* JSObject::SetPropertyWithFailedAccessCheck(LookupResult* result, | 1892 MaybeObject* JSObject::SetPropertyWithFailedAccessCheck(LookupResult* result, |
1853 String* name, | 1893 String* name, |
1854 Object* value, | 1894 Object* value, |
1855 bool check_prototype) { | 1895 bool check_prototype) { |
| 1896 Heap* heap = GetHeap(); |
1856 if (check_prototype && !result->IsProperty()) { | 1897 if (check_prototype && !result->IsProperty()) { |
1857 LookupCallbackSetterInPrototypes(name, result); | 1898 LookupCallbackSetterInPrototypes(name, result); |
1858 } | 1899 } |
1859 | 1900 |
1860 if (result->IsProperty()) { | 1901 if (result->IsProperty()) { |
1861 if (!result->IsReadOnly()) { | 1902 if (!result->IsReadOnly()) { |
1862 switch (result->type()) { | 1903 switch (result->type()) { |
1863 case CALLBACKS: { | 1904 case CALLBACKS: { |
1864 Object* obj = result->GetCallbackObject(); | 1905 Object* obj = result->GetCallbackObject(); |
1865 if (obj->IsAccessorInfo()) { | 1906 if (obj->IsAccessorInfo()) { |
(...skipping 20 matching lines...) Expand all Loading... |
1886 } | 1927 } |
1887 default: { | 1928 default: { |
1888 break; | 1929 break; |
1889 } | 1930 } |
1890 } | 1931 } |
1891 } | 1932 } |
1892 } | 1933 } |
1893 | 1934 |
1894 HandleScope scope; | 1935 HandleScope scope; |
1895 Handle<Object> value_handle(value); | 1936 Handle<Object> value_handle(value); |
1896 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); | 1937 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET); |
1897 return *value_handle; | 1938 return *value_handle; |
1898 } | 1939 } |
1899 | 1940 |
1900 | 1941 |
1901 MaybeObject* JSObject::SetProperty(LookupResult* result, | 1942 MaybeObject* JSObject::SetProperty(LookupResult* result, |
1902 String* name, | 1943 String* name, |
1903 Object* value, | 1944 Object* value, |
1904 PropertyAttributes attributes, | 1945 PropertyAttributes attributes, |
1905 StrictModeFlag strict_mode) { | 1946 StrictModeFlag strict_mode) { |
| 1947 Heap* heap = GetHeap(); |
1906 // Make sure that the top context does not change when doing callbacks or | 1948 // Make sure that the top context does not change when doing callbacks or |
1907 // interceptor calls. | 1949 // interceptor calls. |
1908 AssertNoContextChange ncc; | 1950 AssertNoContextChange ncc; |
1909 | 1951 |
1910 // Optimization for 2-byte strings often used as keys in a decompression | 1952 // Optimization for 2-byte strings often used as keys in a decompression |
1911 // dictionary. We make these short keys into symbols to avoid constantly | 1953 // dictionary. We make these short keys into symbols to avoid constantly |
1912 // reallocating them. | 1954 // reallocating them. |
1913 if (!name->IsSymbol() && name->length() <= 2) { | 1955 if (!name->IsSymbol() && name->length() <= 2) { |
1914 Object* symbol_version; | 1956 Object* symbol_version; |
1915 { MaybeObject* maybe_symbol_version = Heap::LookupSymbol(name); | 1957 { MaybeObject* maybe_symbol_version = heap->LookupSymbol(name); |
1916 if (maybe_symbol_version->ToObject(&symbol_version)) { | 1958 if (maybe_symbol_version->ToObject(&symbol_version)) { |
1917 name = String::cast(symbol_version); | 1959 name = String::cast(symbol_version); |
1918 } | 1960 } |
1919 } | 1961 } |
1920 } | 1962 } |
1921 | 1963 |
1922 // Check access rights if needed. | 1964 // Check access rights if needed. |
1923 if (IsAccessCheckNeeded() | 1965 if (IsAccessCheckNeeded() |
1924 && !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) { | 1966 && !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_SET)) { |
1925 return SetPropertyWithFailedAccessCheck(result, name, value, true); | 1967 return SetPropertyWithFailedAccessCheck(result, name, value, true); |
1926 } | 1968 } |
1927 | 1969 |
1928 if (IsJSGlobalProxy()) { | 1970 if (IsJSGlobalProxy()) { |
1929 Object* proto = GetPrototype(); | 1971 Object* proto = GetPrototype(); |
1930 if (proto->IsNull()) return value; | 1972 if (proto->IsNull()) return value; |
1931 ASSERT(proto->IsJSGlobalObject()); | 1973 ASSERT(proto->IsJSGlobalObject()); |
1932 return JSObject::cast(proto)->SetProperty( | 1974 return JSObject::cast(proto)->SetProperty( |
1933 result, name, value, attributes, strict_mode); | 1975 result, name, value, attributes, strict_mode); |
1934 } | 1976 } |
(...skipping 13 matching lines...) Expand all Loading... |
1948 if (!result->IsFound()) { | 1990 if (!result->IsFound()) { |
1949 // Neither properties nor transitions found. | 1991 // Neither properties nor transitions found. |
1950 return AddProperty(name, value, attributes); | 1992 return AddProperty(name, value, attributes); |
1951 } | 1993 } |
1952 if (result->IsReadOnly() && result->IsProperty()) { | 1994 if (result->IsReadOnly() && result->IsProperty()) { |
1953 if (strict_mode == kStrictMode) { | 1995 if (strict_mode == kStrictMode) { |
1954 HandleScope scope; | 1996 HandleScope scope; |
1955 Handle<String> key(name); | 1997 Handle<String> key(name); |
1956 Handle<Object> holder(this); | 1998 Handle<Object> holder(this); |
1957 Handle<Object> args[2] = { key, holder }; | 1999 Handle<Object> args[2] = { key, holder }; |
1958 return Top::Throw(*Factory::NewTypeError("strict_read_only_property", | 2000 return heap->isolate()->Throw(*heap->isolate()->factory()->NewTypeError( |
1959 HandleVector(args, 2))); | 2001 "strict_read_only_property", HandleVector(args, 2))); |
1960 } else { | 2002 } else { |
1961 return value; | 2003 return value; |
1962 } | 2004 } |
1963 } | 2005 } |
1964 // This is a real property that is not read-only, or it is a | 2006 // This is a real property that is not read-only, or it is a |
1965 // transition or null descriptor and there are no setters in the prototypes. | 2007 // transition or null descriptor and there are no setters in the prototypes. |
1966 switch (result->type()) { | 2008 switch (result->type()) { |
1967 case NORMAL: | 2009 case NORMAL: |
1968 return SetNormalizedProperty(result, value); | 2010 return SetNormalizedProperty(result, value); |
1969 case FIELD: | 2011 case FIELD: |
(...skipping 22 matching lines...) Expand all Loading... |
1992 case CONSTANT_TRANSITION: { | 2034 case CONSTANT_TRANSITION: { |
1993 // If the same constant function is being added we can simply | 2035 // If the same constant function is being added we can simply |
1994 // transition to the target map. | 2036 // transition to the target map. |
1995 Map* target_map = result->GetTransitionMap(); | 2037 Map* target_map = result->GetTransitionMap(); |
1996 DescriptorArray* target_descriptors = target_map->instance_descriptors(); | 2038 DescriptorArray* target_descriptors = target_map->instance_descriptors(); |
1997 int number = target_descriptors->SearchWithCache(name); | 2039 int number = target_descriptors->SearchWithCache(name); |
1998 ASSERT(number != DescriptorArray::kNotFound); | 2040 ASSERT(number != DescriptorArray::kNotFound); |
1999 ASSERT(target_descriptors->GetType(number) == CONSTANT_FUNCTION); | 2041 ASSERT(target_descriptors->GetType(number) == CONSTANT_FUNCTION); |
2000 JSFunction* function = | 2042 JSFunction* function = |
2001 JSFunction::cast(target_descriptors->GetValue(number)); | 2043 JSFunction::cast(target_descriptors->GetValue(number)); |
2002 ASSERT(!Heap::InNewSpace(function)); | 2044 ASSERT(!HEAP->InNewSpace(function)); |
2003 if (value == function) { | 2045 if (value == function) { |
2004 set_map(target_map); | 2046 set_map(target_map); |
2005 return value; | 2047 return value; |
2006 } | 2048 } |
2007 // Otherwise, replace with a MAP_TRANSITION to a new map with a | 2049 // Otherwise, replace with a MAP_TRANSITION to a new map with a |
2008 // FIELD, even if the value is a constant function. | 2050 // FIELD, even if the value is a constant function. |
2009 return ConvertDescriptorToFieldAndMapTransition(name, value, attributes); | 2051 return ConvertDescriptorToFieldAndMapTransition(name, value, attributes); |
2010 } | 2052 } |
2011 case NULL_DESCRIPTOR: | 2053 case NULL_DESCRIPTOR: |
2012 return ConvertDescriptorToFieldAndMapTransition(name, value, attributes); | 2054 return ConvertDescriptorToFieldAndMapTransition(name, value, attributes); |
2013 default: | 2055 default: |
2014 UNREACHABLE(); | 2056 UNREACHABLE(); |
2015 } | 2057 } |
2016 UNREACHABLE(); | 2058 UNREACHABLE(); |
2017 return value; | 2059 return value; |
2018 } | 2060 } |
2019 | 2061 |
2020 | 2062 |
2021 // Set a real local property, even if it is READ_ONLY. If the property is not | 2063 // Set a real local property, even if it is READ_ONLY. If the property is not |
2022 // present, add it with attributes NONE. This code is an exact clone of | 2064 // present, add it with attributes NONE. This code is an exact clone of |
2023 // SetProperty, with the check for IsReadOnly and the check for a | 2065 // SetProperty, with the check for IsReadOnly and the check for a |
2024 // callback setter removed. The two lines looking up the LookupResult | 2066 // callback setter removed. The two lines looking up the LookupResult |
2025 // result are also added. If one of the functions is changed, the other | 2067 // result are also added. If one of the functions is changed, the other |
2026 // should be. | 2068 // should be. |
2027 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( | 2069 MaybeObject* JSObject::SetLocalPropertyIgnoreAttributes( |
2028 String* name, | 2070 String* name, |
2029 Object* value, | 2071 Object* value, |
2030 PropertyAttributes attributes) { | 2072 PropertyAttributes attributes) { |
| 2073 Heap* heap = GetHeap(); |
| 2074 |
2031 // Make sure that the top context does not change when doing callbacks or | 2075 // Make sure that the top context does not change when doing callbacks or |
2032 // interceptor calls. | 2076 // interceptor calls. |
2033 AssertNoContextChange ncc; | 2077 AssertNoContextChange ncc; |
2034 LookupResult result; | 2078 LookupResult result; |
2035 LocalLookup(name, &result); | 2079 LocalLookup(name, &result); |
2036 // Check access rights if needed. | 2080 // Check access rights if needed. |
2037 if (IsAccessCheckNeeded() | 2081 if (IsAccessCheckNeeded() |
2038 && !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) { | 2082 && !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_SET)) { |
2039 return SetPropertyWithFailedAccessCheck(&result, name, value, false); | 2083 return SetPropertyWithFailedAccessCheck(&result, name, value, false); |
2040 } | 2084 } |
2041 | 2085 |
2042 if (IsJSGlobalProxy()) { | 2086 if (IsJSGlobalProxy()) { |
2043 Object* proto = GetPrototype(); | 2087 Object* proto = GetPrototype(); |
2044 if (proto->IsNull()) return value; | 2088 if (proto->IsNull()) return value; |
2045 ASSERT(proto->IsJSGlobalObject()); | 2089 ASSERT(proto->IsJSGlobalObject()); |
2046 return JSObject::cast(proto)->SetLocalPropertyIgnoreAttributes( | 2090 return JSObject::cast(proto)->SetLocalPropertyIgnoreAttributes( |
2047 name, | 2091 name, |
2048 value, | 2092 value, |
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2100 String* name, | 2144 String* name, |
2101 bool continue_search) { | 2145 bool continue_search) { |
2102 // Check local property, ignore interceptor. | 2146 // Check local property, ignore interceptor. |
2103 LookupResult result; | 2147 LookupResult result; |
2104 LocalLookupRealNamedProperty(name, &result); | 2148 LocalLookupRealNamedProperty(name, &result); |
2105 if (result.IsProperty()) return result.GetAttributes(); | 2149 if (result.IsProperty()) return result.GetAttributes(); |
2106 | 2150 |
2107 if (continue_search) { | 2151 if (continue_search) { |
2108 // Continue searching via the prototype chain. | 2152 // Continue searching via the prototype chain. |
2109 Object* pt = GetPrototype(); | 2153 Object* pt = GetPrototype(); |
2110 if (pt != Heap::null_value()) { | 2154 if (!pt->IsNull()) { |
2111 return JSObject::cast(pt)-> | 2155 return JSObject::cast(pt)-> |
2112 GetPropertyAttributeWithReceiver(receiver, name); | 2156 GetPropertyAttributeWithReceiver(receiver, name); |
2113 } | 2157 } |
2114 } | 2158 } |
2115 return ABSENT; | 2159 return ABSENT; |
2116 } | 2160 } |
2117 | 2161 |
2118 | 2162 |
2119 PropertyAttributes JSObject::GetPropertyAttributeWithInterceptor( | 2163 PropertyAttributes JSObject::GetPropertyAttributeWithInterceptor( |
2120 JSObject* receiver, | 2164 JSObject* receiver, |
2121 String* name, | 2165 String* name, |
2122 bool continue_search) { | 2166 bool continue_search) { |
| 2167 Isolate* isolate = GetIsolate(); |
| 2168 |
2123 // Make sure that the top context does not change when doing | 2169 // Make sure that the top context does not change when doing |
2124 // callbacks or interceptor calls. | 2170 // callbacks or interceptor calls. |
2125 AssertNoContextChange ncc; | 2171 AssertNoContextChange ncc; |
2126 | 2172 |
2127 HandleScope scope; | 2173 HandleScope scope(isolate); |
2128 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); | 2174 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); |
2129 Handle<JSObject> receiver_handle(receiver); | 2175 Handle<JSObject> receiver_handle(receiver); |
2130 Handle<JSObject> holder_handle(this); | 2176 Handle<JSObject> holder_handle(this); |
2131 Handle<String> name_handle(name); | 2177 Handle<String> name_handle(name); |
2132 CustomArguments args(interceptor->data(), receiver, this); | 2178 CustomArguments args(isolate, interceptor->data(), receiver, this); |
2133 v8::AccessorInfo info(args.end()); | 2179 v8::AccessorInfo info(args.end()); |
2134 if (!interceptor->query()->IsUndefined()) { | 2180 if (!interceptor->query()->IsUndefined()) { |
2135 v8::NamedPropertyQuery query = | 2181 v8::NamedPropertyQuery query = |
2136 v8::ToCData<v8::NamedPropertyQuery>(interceptor->query()); | 2182 v8::ToCData<v8::NamedPropertyQuery>(interceptor->query()); |
2137 LOG(ApiNamedPropertyAccess("interceptor-named-has", *holder_handle, name)); | 2183 LOG(isolate, |
| 2184 ApiNamedPropertyAccess("interceptor-named-has", *holder_handle, name)); |
2138 v8::Handle<v8::Integer> result; | 2185 v8::Handle<v8::Integer> result; |
2139 { | 2186 { |
2140 // Leaving JavaScript. | 2187 // Leaving JavaScript. |
2141 VMState state(EXTERNAL); | 2188 VMState state(isolate, EXTERNAL); |
2142 result = query(v8::Utils::ToLocal(name_handle), info); | 2189 result = query(v8::Utils::ToLocal(name_handle), info); |
2143 } | 2190 } |
2144 if (!result.IsEmpty()) { | 2191 if (!result.IsEmpty()) { |
2145 ASSERT(result->IsInt32()); | 2192 ASSERT(result->IsInt32()); |
2146 return static_cast<PropertyAttributes>(result->Int32Value()); | 2193 return static_cast<PropertyAttributes>(result->Int32Value()); |
2147 } | 2194 } |
2148 } else if (!interceptor->getter()->IsUndefined()) { | 2195 } else if (!interceptor->getter()->IsUndefined()) { |
2149 v8::NamedPropertyGetter getter = | 2196 v8::NamedPropertyGetter getter = |
2150 v8::ToCData<v8::NamedPropertyGetter>(interceptor->getter()); | 2197 v8::ToCData<v8::NamedPropertyGetter>(interceptor->getter()); |
2151 LOG(ApiNamedPropertyAccess("interceptor-named-get-has", this, name)); | 2198 LOG(isolate, |
| 2199 ApiNamedPropertyAccess("interceptor-named-get-has", this, name)); |
2152 v8::Handle<v8::Value> result; | 2200 v8::Handle<v8::Value> result; |
2153 { | 2201 { |
2154 // Leaving JavaScript. | 2202 // Leaving JavaScript. |
2155 VMState state(EXTERNAL); | 2203 VMState state(isolate, EXTERNAL); |
2156 result = getter(v8::Utils::ToLocal(name_handle), info); | 2204 result = getter(v8::Utils::ToLocal(name_handle), info); |
2157 } | 2205 } |
2158 if (!result.IsEmpty()) return DONT_ENUM; | 2206 if (!result.IsEmpty()) return DONT_ENUM; |
2159 } | 2207 } |
2160 return holder_handle->GetPropertyAttributePostInterceptor(*receiver_handle, | 2208 return holder_handle->GetPropertyAttributePostInterceptor(*receiver_handle, |
2161 *name_handle, | 2209 *name_handle, |
2162 continue_search); | 2210 continue_search); |
2163 } | 2211 } |
2164 | 2212 |
2165 | 2213 |
2166 PropertyAttributes JSObject::GetPropertyAttributeWithReceiver( | 2214 PropertyAttributes JSObject::GetPropertyAttributeWithReceiver( |
2167 JSObject* receiver, | 2215 JSObject* receiver, |
2168 String* key) { | 2216 String* key) { |
2169 uint32_t index = 0; | 2217 uint32_t index = 0; |
2170 if (key->AsArrayIndex(&index)) { | 2218 if (key->AsArrayIndex(&index)) { |
2171 if (HasElementWithReceiver(receiver, index)) return NONE; | 2219 if (HasElementWithReceiver(receiver, index)) return NONE; |
2172 return ABSENT; | 2220 return ABSENT; |
2173 } | 2221 } |
2174 // Named property. | 2222 // Named property. |
2175 LookupResult result; | 2223 LookupResult result; |
2176 Lookup(key, &result); | 2224 Lookup(key, &result); |
2177 return GetPropertyAttribute(receiver, &result, key, true); | 2225 return GetPropertyAttribute(receiver, &result, key, true); |
2178 } | 2226 } |
2179 | 2227 |
2180 | 2228 |
2181 PropertyAttributes JSObject::GetPropertyAttribute(JSObject* receiver, | 2229 PropertyAttributes JSObject::GetPropertyAttribute(JSObject* receiver, |
2182 LookupResult* result, | 2230 LookupResult* result, |
2183 String* name, | 2231 String* name, |
2184 bool continue_search) { | 2232 bool continue_search) { |
| 2233 Heap* heap = GetHeap(); |
2185 // Check access rights if needed. | 2234 // Check access rights if needed. |
2186 if (IsAccessCheckNeeded() && | 2235 if (IsAccessCheckNeeded() && |
2187 !Top::MayNamedAccess(this, name, v8::ACCESS_HAS)) { | 2236 !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_HAS)) { |
2188 return GetPropertyAttributeWithFailedAccessCheck(receiver, | 2237 return GetPropertyAttributeWithFailedAccessCheck(receiver, |
2189 result, | 2238 result, |
2190 name, | 2239 name, |
2191 continue_search); | 2240 continue_search); |
2192 } | 2241 } |
2193 if (result->IsProperty()) { | 2242 if (result->IsProperty()) { |
2194 switch (result->type()) { | 2243 switch (result->type()) { |
2195 case NORMAL: // fall through | 2244 case NORMAL: // fall through |
2196 case FIELD: | 2245 case FIELD: |
2197 case CONSTANT_FUNCTION: | 2246 case CONSTANT_FUNCTION: |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2243 } | 2292 } |
2244 #endif | 2293 #endif |
2245 return result; | 2294 return result; |
2246 } | 2295 } |
2247 | 2296 |
2248 { MaybeObject* maybe_result = | 2297 { MaybeObject* maybe_result = |
2249 fast->CopyNormalized(mode, SHARED_NORMALIZED_MAP); | 2298 fast->CopyNormalized(mode, SHARED_NORMALIZED_MAP); |
2250 if (!maybe_result->ToObject(&result)) return maybe_result; | 2299 if (!maybe_result->ToObject(&result)) return maybe_result; |
2251 } | 2300 } |
2252 set(index, result); | 2301 set(index, result); |
2253 Counters::normalized_maps.Increment(); | 2302 COUNTERS->normalized_maps()->Increment(); |
2254 | 2303 |
2255 return result; | 2304 return result; |
2256 } | 2305 } |
2257 | 2306 |
2258 | 2307 |
2259 void NormalizedMapCache::Clear() { | 2308 void NormalizedMapCache::Clear() { |
2260 int entries = length(); | 2309 int entries = length(); |
2261 for (int i = 0; i != entries; i++) { | 2310 for (int i = 0; i != entries; i++) { |
2262 set_undefined(i); | 2311 set_undefined(i); |
2263 } | 2312 } |
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2303 MaybeObject* JSObject::UpdateMapCodeCache(String* name, Code* code) { | 2352 MaybeObject* JSObject::UpdateMapCodeCache(String* name, Code* code) { |
2304 if (map()->is_shared()) { | 2353 if (map()->is_shared()) { |
2305 // Fast case maps are never marked as shared. | 2354 // Fast case maps are never marked as shared. |
2306 ASSERT(!HasFastProperties()); | 2355 ASSERT(!HasFastProperties()); |
2307 // Replace the map with an identical copy that can be safely modified. | 2356 // Replace the map with an identical copy that can be safely modified. |
2308 Object* obj; | 2357 Object* obj; |
2309 { MaybeObject* maybe_obj = map()->CopyNormalized(KEEP_INOBJECT_PROPERTIES, | 2358 { MaybeObject* maybe_obj = map()->CopyNormalized(KEEP_INOBJECT_PROPERTIES, |
2310 UNIQUE_NORMALIZED_MAP); | 2359 UNIQUE_NORMALIZED_MAP); |
2311 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 2360 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
2312 } | 2361 } |
2313 Counters::normalized_maps.Increment(); | 2362 COUNTERS->normalized_maps()->Increment(); |
2314 | 2363 |
2315 set_map(Map::cast(obj)); | 2364 set_map(Map::cast(obj)); |
2316 } | 2365 } |
2317 return map()->UpdateCodeCache(name, code); | 2366 return map()->UpdateCodeCache(name, code); |
2318 } | 2367 } |
2319 | 2368 |
2320 | 2369 |
2321 MaybeObject* JSObject::NormalizeProperties(PropertyNormalizationMode mode, | 2370 MaybeObject* JSObject::NormalizeProperties(PropertyNormalizationMode mode, |
2322 int expected_additional_properties) { | 2371 int expected_additional_properties) { |
2323 if (!HasFastProperties()) return this; | 2372 if (!HasFastProperties()) return this; |
2324 | 2373 |
2325 // The global object is always normalized. | 2374 // The global object is always normalized. |
2326 ASSERT(!IsGlobalObject()); | 2375 ASSERT(!IsGlobalObject()); |
2327 | |
2328 // JSGlobalProxy must never be normalized | 2376 // JSGlobalProxy must never be normalized |
2329 ASSERT(!IsJSGlobalProxy()); | 2377 ASSERT(!IsJSGlobalProxy()); |
2330 | 2378 |
| 2379 Heap* heap = GetHeap(); |
| 2380 |
2331 // Allocate new content. | 2381 // Allocate new content. |
2332 int property_count = map()->NumberOfDescribedProperties(); | 2382 int property_count = map()->NumberOfDescribedProperties(); |
2333 if (expected_additional_properties > 0) { | 2383 if (expected_additional_properties > 0) { |
2334 property_count += expected_additional_properties; | 2384 property_count += expected_additional_properties; |
2335 } else { | 2385 } else { |
2336 property_count += 2; // Make space for two more properties. | 2386 property_count += 2; // Make space for two more properties. |
2337 } | 2387 } |
2338 Object* obj; | 2388 Object* obj; |
2339 { MaybeObject* maybe_obj = | 2389 { MaybeObject* maybe_obj = |
2340 StringDictionary::Allocate(property_count); | 2390 StringDictionary::Allocate(property_count); |
(...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2389 break; | 2439 break; |
2390 default: | 2440 default: |
2391 UNREACHABLE(); | 2441 UNREACHABLE(); |
2392 } | 2442 } |
2393 } | 2443 } |
2394 | 2444 |
2395 // Copy the next enumeration index from instance descriptor. | 2445 // Copy the next enumeration index from instance descriptor. |
2396 int index = map()->instance_descriptors()->NextEnumerationIndex(); | 2446 int index = map()->instance_descriptors()->NextEnumerationIndex(); |
2397 dictionary->SetNextEnumerationIndex(index); | 2447 dictionary->SetNextEnumerationIndex(index); |
2398 | 2448 |
2399 { MaybeObject* maybe_obj = Top::context()->global_context()-> | 2449 { MaybeObject* maybe_obj = heap->isolate()->context()->global_context()-> |
2400 normalized_map_cache()->Get(this, mode); | 2450 normalized_map_cache()->Get(this, mode); |
2401 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 2451 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
2402 } | 2452 } |
2403 Map* new_map = Map::cast(obj); | 2453 Map* new_map = Map::cast(obj); |
2404 | 2454 |
2405 // We have now successfully allocated all the necessary objects. | 2455 // We have now successfully allocated all the necessary objects. |
2406 // Changes can now be made with the guarantee that all of them take effect. | 2456 // Changes can now be made with the guarantee that all of them take effect. |
2407 | 2457 |
2408 // Resize the object in the heap if necessary. | 2458 // Resize the object in the heap if necessary. |
2409 int new_instance_size = new_map->instance_size(); | 2459 int new_instance_size = new_map->instance_size(); |
2410 int instance_size_delta = map()->instance_size() - new_instance_size; | 2460 int instance_size_delta = map()->instance_size() - new_instance_size; |
2411 ASSERT(instance_size_delta >= 0); | 2461 ASSERT(instance_size_delta >= 0); |
2412 Heap::CreateFillerObjectAt(this->address() + new_instance_size, | 2462 heap->CreateFillerObjectAt(this->address() + new_instance_size, |
2413 instance_size_delta); | 2463 instance_size_delta); |
2414 | 2464 |
2415 set_map(new_map); | 2465 set_map(new_map); |
| 2466 map()->set_instance_descriptors(heap->empty_descriptor_array()); |
2416 | 2467 |
2417 set_properties(dictionary); | 2468 set_properties(dictionary); |
2418 | 2469 |
2419 Counters::props_to_dictionary.Increment(); | 2470 heap->isolate()->counters()->props_to_dictionary()->Increment(); |
2420 | 2471 |
2421 #ifdef DEBUG | 2472 #ifdef DEBUG |
2422 if (FLAG_trace_normalization) { | 2473 if (FLAG_trace_normalization) { |
2423 PrintF("Object properties have been normalized:\n"); | 2474 PrintF("Object properties have been normalized:\n"); |
2424 Print(); | 2475 Print(); |
2425 } | 2476 } |
2426 #endif | 2477 #endif |
2427 return this; | 2478 return this; |
2428 } | 2479 } |
2429 | 2480 |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2470 } | 2521 } |
2471 dictionary = NumberDictionary::cast(result); | 2522 dictionary = NumberDictionary::cast(result); |
2472 } | 2523 } |
2473 } | 2524 } |
2474 // Switch to using the dictionary as the backing storage for | 2525 // Switch to using the dictionary as the backing storage for |
2475 // elements. Set the new map first to satify the elements type | 2526 // elements. Set the new map first to satify the elements type |
2476 // assert in set_elements(). | 2527 // assert in set_elements(). |
2477 set_map(new_map); | 2528 set_map(new_map); |
2478 set_elements(dictionary); | 2529 set_elements(dictionary); |
2479 | 2530 |
2480 Counters::elements_to_dictionary.Increment(); | 2531 new_map->GetHeap()->isolate()->counters()->elements_to_dictionary()-> |
| 2532 Increment(); |
2481 | 2533 |
2482 #ifdef DEBUG | 2534 #ifdef DEBUG |
2483 if (FLAG_trace_normalization) { | 2535 if (FLAG_trace_normalization) { |
2484 PrintF("Object elements have been normalized:\n"); | 2536 PrintF("Object elements have been normalized:\n"); |
2485 Print(); | 2537 Print(); |
2486 } | 2538 } |
2487 #endif | 2539 #endif |
2488 | 2540 |
2489 return this; | 2541 return this; |
2490 } | 2542 } |
2491 | 2543 |
2492 | 2544 |
2493 MaybeObject* JSObject::DeletePropertyPostInterceptor(String* name, | 2545 MaybeObject* JSObject::DeletePropertyPostInterceptor(String* name, |
2494 DeleteMode mode) { | 2546 DeleteMode mode) { |
2495 // Check local property, ignore interceptor. | 2547 // Check local property, ignore interceptor. |
| 2548 Heap* heap = GetHeap(); |
2496 LookupResult result; | 2549 LookupResult result; |
2497 LocalLookupRealNamedProperty(name, &result); | 2550 LocalLookupRealNamedProperty(name, &result); |
2498 if (!result.IsProperty()) return Heap::true_value(); | 2551 if (!result.IsProperty()) return heap->true_value(); |
2499 | 2552 |
2500 // Normalize object if needed. | 2553 // Normalize object if needed. |
2501 Object* obj; | 2554 Object* obj; |
2502 { MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 2555 { MaybeObject* maybe_obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
2503 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 2556 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
2504 } | 2557 } |
2505 | 2558 |
2506 return DeleteNormalizedProperty(name, mode); | 2559 return DeleteNormalizedProperty(name, mode); |
2507 } | 2560 } |
2508 | 2561 |
2509 | 2562 |
2510 MaybeObject* JSObject::DeletePropertyWithInterceptor(String* name) { | 2563 MaybeObject* JSObject::DeletePropertyWithInterceptor(String* name) { |
2511 HandleScope scope; | 2564 Isolate* isolate = GetIsolate(); |
| 2565 HandleScope scope(isolate); |
2512 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); | 2566 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); |
2513 Handle<String> name_handle(name); | 2567 Handle<String> name_handle(name); |
2514 Handle<JSObject> this_handle(this); | 2568 Handle<JSObject> this_handle(this); |
2515 if (!interceptor->deleter()->IsUndefined()) { | 2569 if (!interceptor->deleter()->IsUndefined()) { |
2516 v8::NamedPropertyDeleter deleter = | 2570 v8::NamedPropertyDeleter deleter = |
2517 v8::ToCData<v8::NamedPropertyDeleter>(interceptor->deleter()); | 2571 v8::ToCData<v8::NamedPropertyDeleter>(interceptor->deleter()); |
2518 LOG(ApiNamedPropertyAccess("interceptor-named-delete", *this_handle, name)); | 2572 LOG(isolate, |
2519 CustomArguments args(interceptor->data(), this, this); | 2573 ApiNamedPropertyAccess("interceptor-named-delete", *this_handle, name)); |
| 2574 CustomArguments args(isolate, interceptor->data(), this, this); |
2520 v8::AccessorInfo info(args.end()); | 2575 v8::AccessorInfo info(args.end()); |
2521 v8::Handle<v8::Boolean> result; | 2576 v8::Handle<v8::Boolean> result; |
2522 { | 2577 { |
2523 // Leaving JavaScript. | 2578 // Leaving JavaScript. |
2524 VMState state(EXTERNAL); | 2579 VMState state(isolate, EXTERNAL); |
2525 result = deleter(v8::Utils::ToLocal(name_handle), info); | 2580 result = deleter(v8::Utils::ToLocal(name_handle), info); |
2526 } | 2581 } |
2527 RETURN_IF_SCHEDULED_EXCEPTION(); | 2582 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
2528 if (!result.IsEmpty()) { | 2583 if (!result.IsEmpty()) { |
2529 ASSERT(result->IsBoolean()); | 2584 ASSERT(result->IsBoolean()); |
2530 return *v8::Utils::OpenHandle(*result); | 2585 return *v8::Utils::OpenHandle(*result); |
2531 } | 2586 } |
2532 } | 2587 } |
2533 MaybeObject* raw_result = | 2588 MaybeObject* raw_result = |
2534 this_handle->DeletePropertyPostInterceptor(*name_handle, NORMAL_DELETION); | 2589 this_handle->DeletePropertyPostInterceptor(*name_handle, NORMAL_DELETION); |
2535 RETURN_IF_SCHEDULED_EXCEPTION(); | 2590 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
2536 return raw_result; | 2591 return raw_result; |
2537 } | 2592 } |
2538 | 2593 |
2539 | 2594 |
2540 MaybeObject* JSObject::DeleteElementPostInterceptor(uint32_t index, | 2595 MaybeObject* JSObject::DeleteElementPostInterceptor(uint32_t index, |
2541 DeleteMode mode) { | 2596 DeleteMode mode) { |
| 2597 Heap* heap = GetHeap(); |
2542 ASSERT(!HasExternalArrayElements()); | 2598 ASSERT(!HasExternalArrayElements()); |
2543 switch (GetElementsKind()) { | 2599 switch (GetElementsKind()) { |
2544 case FAST_ELEMENTS: { | 2600 case FAST_ELEMENTS: { |
2545 Object* obj; | 2601 Object* obj; |
2546 { MaybeObject* maybe_obj = EnsureWritableFastElements(); | 2602 { MaybeObject* maybe_obj = EnsureWritableFastElements(); |
2547 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 2603 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
2548 } | 2604 } |
2549 uint32_t length = IsJSArray() ? | 2605 uint32_t length = IsJSArray() ? |
2550 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : | 2606 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : |
2551 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | 2607 static_cast<uint32_t>(FixedArray::cast(elements())->length()); |
2552 if (index < length) { | 2608 if (index < length) { |
2553 FixedArray::cast(elements())->set_the_hole(index); | 2609 FixedArray::cast(elements())->set_the_hole(index); |
2554 } | 2610 } |
2555 break; | 2611 break; |
2556 } | 2612 } |
2557 case DICTIONARY_ELEMENTS: { | 2613 case DICTIONARY_ELEMENTS: { |
2558 NumberDictionary* dictionary = element_dictionary(); | 2614 NumberDictionary* dictionary = element_dictionary(); |
2559 int entry = dictionary->FindEntry(index); | 2615 int entry = dictionary->FindEntry(index); |
2560 if (entry != NumberDictionary::kNotFound) { | 2616 if (entry != NumberDictionary::kNotFound) { |
2561 return dictionary->DeleteProperty(entry, mode); | 2617 return dictionary->DeleteProperty(entry, mode); |
2562 } | 2618 } |
2563 break; | 2619 break; |
2564 } | 2620 } |
2565 default: | 2621 default: |
2566 UNREACHABLE(); | 2622 UNREACHABLE(); |
2567 break; | 2623 break; |
2568 } | 2624 } |
2569 return Heap::true_value(); | 2625 return heap->true_value(); |
2570 } | 2626 } |
2571 | 2627 |
2572 | 2628 |
2573 MaybeObject* JSObject::DeleteElementWithInterceptor(uint32_t index) { | 2629 MaybeObject* JSObject::DeleteElementWithInterceptor(uint32_t index) { |
| 2630 Isolate* isolate = GetIsolate(); |
| 2631 Heap* heap = isolate->heap(); |
2574 // Make sure that the top context does not change when doing | 2632 // Make sure that the top context does not change when doing |
2575 // callbacks or interceptor calls. | 2633 // callbacks or interceptor calls. |
2576 AssertNoContextChange ncc; | 2634 AssertNoContextChange ncc; |
2577 HandleScope scope; | 2635 HandleScope scope(isolate); |
2578 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); | 2636 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); |
2579 if (interceptor->deleter()->IsUndefined()) return Heap::false_value(); | 2637 if (interceptor->deleter()->IsUndefined()) return heap->false_value(); |
2580 v8::IndexedPropertyDeleter deleter = | 2638 v8::IndexedPropertyDeleter deleter = |
2581 v8::ToCData<v8::IndexedPropertyDeleter>(interceptor->deleter()); | 2639 v8::ToCData<v8::IndexedPropertyDeleter>(interceptor->deleter()); |
2582 Handle<JSObject> this_handle(this); | 2640 Handle<JSObject> this_handle(this); |
2583 LOG(ApiIndexedPropertyAccess("interceptor-indexed-delete", this, index)); | 2641 LOG(isolate, |
2584 CustomArguments args(interceptor->data(), this, this); | 2642 ApiIndexedPropertyAccess("interceptor-indexed-delete", this, index)); |
| 2643 CustomArguments args(isolate, interceptor->data(), this, this); |
2585 v8::AccessorInfo info(args.end()); | 2644 v8::AccessorInfo info(args.end()); |
2586 v8::Handle<v8::Boolean> result; | 2645 v8::Handle<v8::Boolean> result; |
2587 { | 2646 { |
2588 // Leaving JavaScript. | 2647 // Leaving JavaScript. |
2589 VMState state(EXTERNAL); | 2648 VMState state(isolate, EXTERNAL); |
2590 result = deleter(index, info); | 2649 result = deleter(index, info); |
2591 } | 2650 } |
2592 RETURN_IF_SCHEDULED_EXCEPTION(); | 2651 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
2593 if (!result.IsEmpty()) { | 2652 if (!result.IsEmpty()) { |
2594 ASSERT(result->IsBoolean()); | 2653 ASSERT(result->IsBoolean()); |
2595 return *v8::Utils::OpenHandle(*result); | 2654 return *v8::Utils::OpenHandle(*result); |
2596 } | 2655 } |
2597 MaybeObject* raw_result = | 2656 MaybeObject* raw_result = |
2598 this_handle->DeleteElementPostInterceptor(index, NORMAL_DELETION); | 2657 this_handle->DeleteElementPostInterceptor(index, NORMAL_DELETION); |
2599 RETURN_IF_SCHEDULED_EXCEPTION(); | 2658 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
2600 return raw_result; | 2659 return raw_result; |
2601 } | 2660 } |
2602 | 2661 |
2603 | 2662 |
2604 MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) { | 2663 MaybeObject* JSObject::DeleteElement(uint32_t index, DeleteMode mode) { |
| 2664 Isolate* isolate = GetIsolate(); |
2605 // Check access rights if needed. | 2665 // Check access rights if needed. |
2606 if (IsAccessCheckNeeded() && | 2666 if (IsAccessCheckNeeded() && |
2607 !Top::MayIndexedAccess(this, index, v8::ACCESS_DELETE)) { | 2667 !isolate->MayIndexedAccess(this, index, v8::ACCESS_DELETE)) { |
2608 Top::ReportFailedAccessCheck(this, v8::ACCESS_DELETE); | 2668 isolate->ReportFailedAccessCheck(this, v8::ACCESS_DELETE); |
2609 return Heap::false_value(); | 2669 return isolate->heap()->false_value(); |
2610 } | 2670 } |
2611 | 2671 |
2612 if (IsJSGlobalProxy()) { | 2672 if (IsJSGlobalProxy()) { |
2613 Object* proto = GetPrototype(); | 2673 Object* proto = GetPrototype(); |
2614 if (proto->IsNull()) return Heap::false_value(); | 2674 if (proto->IsNull()) return isolate->heap()->false_value(); |
2615 ASSERT(proto->IsJSGlobalObject()); | 2675 ASSERT(proto->IsJSGlobalObject()); |
2616 return JSGlobalObject::cast(proto)->DeleteElement(index, mode); | 2676 return JSGlobalObject::cast(proto)->DeleteElement(index, mode); |
2617 } | 2677 } |
2618 | 2678 |
2619 if (HasIndexedInterceptor()) { | 2679 if (HasIndexedInterceptor()) { |
2620 // Skip interceptor if forcing deletion. | 2680 // Skip interceptor if forcing deletion. |
2621 if (mode == FORCE_DELETION) { | 2681 if (mode == FORCE_DELETION) { |
2622 return DeleteElementPostInterceptor(index, mode); | 2682 return DeleteElementPostInterceptor(index, mode); |
2623 } | 2683 } |
2624 return DeleteElementWithInterceptor(index); | 2684 return DeleteElementWithInterceptor(index); |
(...skipping 22 matching lines...) Expand all Loading... |
2647 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 2707 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
2648 case EXTERNAL_FLOAT_ELEMENTS: | 2708 case EXTERNAL_FLOAT_ELEMENTS: |
2649 // Pixel and external array elements cannot be deleted. Just | 2709 // Pixel and external array elements cannot be deleted. Just |
2650 // silently ignore here. | 2710 // silently ignore here. |
2651 break; | 2711 break; |
2652 case DICTIONARY_ELEMENTS: { | 2712 case DICTIONARY_ELEMENTS: { |
2653 NumberDictionary* dictionary = element_dictionary(); | 2713 NumberDictionary* dictionary = element_dictionary(); |
2654 int entry = dictionary->FindEntry(index); | 2714 int entry = dictionary->FindEntry(index); |
2655 if (entry != NumberDictionary::kNotFound) { | 2715 if (entry != NumberDictionary::kNotFound) { |
2656 Object* result = dictionary->DeleteProperty(entry, mode); | 2716 Object* result = dictionary->DeleteProperty(entry, mode); |
2657 if (mode == STRICT_DELETION && result == Heap::false_value()) { | 2717 if (mode == STRICT_DELETION && result == |
| 2718 isolate->heap()->false_value()) { |
2658 // In strict mode, deleting a non-configurable property throws | 2719 // In strict mode, deleting a non-configurable property throws |
2659 // exception. dictionary->DeleteProperty will return false_value() | 2720 // exception. dictionary->DeleteProperty will return false_value() |
2660 // if a non-configurable property is being deleted. | 2721 // if a non-configurable property is being deleted. |
2661 HandleScope scope; | 2722 HandleScope scope; |
2662 Handle<Object> i = Factory::NewNumberFromUint(index); | 2723 Handle<Object> i = isolate->factory()->NewNumberFromUint(index); |
2663 Handle<Object> args[2] = { i, Handle<Object>(this) }; | 2724 Handle<Object> args[2] = { i, Handle<Object>(this) }; |
2664 return Top::Throw(*Factory::NewTypeError("strict_delete_property", | 2725 return isolate->Throw(*isolate->factory()->NewTypeError( |
2665 HandleVector(args, 2))); | 2726 "strict_delete_property", HandleVector(args, 2))); |
2666 } | 2727 } |
2667 } | 2728 } |
2668 break; | 2729 break; |
2669 } | 2730 } |
2670 default: | 2731 default: |
2671 UNREACHABLE(); | 2732 UNREACHABLE(); |
2672 break; | 2733 break; |
2673 } | 2734 } |
2674 return Heap::true_value(); | 2735 return isolate->heap()->true_value(); |
2675 } | 2736 } |
2676 | 2737 |
2677 | 2738 |
2678 MaybeObject* JSObject::DeleteProperty(String* name, DeleteMode mode) { | 2739 MaybeObject* JSObject::DeleteProperty(String* name, DeleteMode mode) { |
| 2740 Isolate* isolate = GetIsolate(); |
2679 // ECMA-262, 3rd, 8.6.2.5 | 2741 // ECMA-262, 3rd, 8.6.2.5 |
2680 ASSERT(name->IsString()); | 2742 ASSERT(name->IsString()); |
2681 | 2743 |
2682 // Check access rights if needed. | 2744 // Check access rights if needed. |
2683 if (IsAccessCheckNeeded() && | 2745 if (IsAccessCheckNeeded() && |
2684 !Top::MayNamedAccess(this, name, v8::ACCESS_DELETE)) { | 2746 !isolate->MayNamedAccess(this, name, v8::ACCESS_DELETE)) { |
2685 Top::ReportFailedAccessCheck(this, v8::ACCESS_DELETE); | 2747 isolate->ReportFailedAccessCheck(this, v8::ACCESS_DELETE); |
2686 return Heap::false_value(); | 2748 return isolate->heap()->false_value(); |
2687 } | 2749 } |
2688 | 2750 |
2689 if (IsJSGlobalProxy()) { | 2751 if (IsJSGlobalProxy()) { |
2690 Object* proto = GetPrototype(); | 2752 Object* proto = GetPrototype(); |
2691 if (proto->IsNull()) return Heap::false_value(); | 2753 if (proto->IsNull()) return isolate->heap()->false_value(); |
2692 ASSERT(proto->IsJSGlobalObject()); | 2754 ASSERT(proto->IsJSGlobalObject()); |
2693 return JSGlobalObject::cast(proto)->DeleteProperty(name, mode); | 2755 return JSGlobalObject::cast(proto)->DeleteProperty(name, mode); |
2694 } | 2756 } |
2695 | 2757 |
2696 uint32_t index = 0; | 2758 uint32_t index = 0; |
2697 if (name->AsArrayIndex(&index)) { | 2759 if (name->AsArrayIndex(&index)) { |
2698 return DeleteElement(index, mode); | 2760 return DeleteElement(index, mode); |
2699 } else { | 2761 } else { |
2700 LookupResult result; | 2762 LookupResult result; |
2701 LocalLookup(name, &result); | 2763 LocalLookup(name, &result); |
2702 if (!result.IsProperty()) return Heap::true_value(); | 2764 if (!result.IsProperty()) return isolate->heap()->true_value(); |
2703 // Ignore attributes if forcing a deletion. | 2765 // Ignore attributes if forcing a deletion. |
2704 if (result.IsDontDelete() && mode != FORCE_DELETION) { | 2766 if (result.IsDontDelete() && mode != FORCE_DELETION) { |
2705 if (mode == STRICT_DELETION) { | 2767 if (mode == STRICT_DELETION) { |
2706 // Deleting a non-configurable property in strict mode. | 2768 // Deleting a non-configurable property in strict mode. |
2707 HandleScope scope; | 2769 HandleScope scope(isolate); |
2708 Handle<Object> args[2] = { Handle<Object>(name), Handle<Object>(this) }; | 2770 Handle<Object> args[2] = { Handle<Object>(name), Handle<Object>(this) }; |
2709 return Top::Throw(*Factory::NewTypeError("strict_delete_property", | 2771 return isolate->Throw(*isolate->factory()->NewTypeError( |
2710 HandleVector(args, 2))); | 2772 "strict_delete_property", HandleVector(args, 2))); |
2711 } | 2773 } |
2712 return Heap::false_value(); | 2774 return isolate->heap()->false_value(); |
2713 } | 2775 } |
2714 // Check for interceptor. | 2776 // Check for interceptor. |
2715 if (result.type() == INTERCEPTOR) { | 2777 if (result.type() == INTERCEPTOR) { |
2716 // Skip interceptor if forcing a deletion. | 2778 // Skip interceptor if forcing a deletion. |
2717 if (mode == FORCE_DELETION) { | 2779 if (mode == FORCE_DELETION) { |
2718 return DeletePropertyPostInterceptor(name, mode); | 2780 return DeletePropertyPostInterceptor(name, mode); |
2719 } | 2781 } |
2720 return DeletePropertyWithInterceptor(name); | 2782 return DeletePropertyWithInterceptor(name); |
2721 } | 2783 } |
2722 // Normalize object if needed. | 2784 // Normalize object if needed. |
2723 Object* obj; | 2785 Object* obj; |
2724 { MaybeObject* maybe_obj = | 2786 { MaybeObject* maybe_obj = |
2725 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 2787 NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
2726 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 2788 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
2727 } | 2789 } |
2728 // Make sure the properties are normalized before removing the entry. | 2790 // Make sure the properties are normalized before removing the entry. |
2729 return DeleteNormalizedProperty(name, mode); | 2791 return DeleteNormalizedProperty(name, mode); |
2730 } | 2792 } |
2731 } | 2793 } |
2732 | 2794 |
2733 | 2795 |
2734 // Check whether this object references another object. | 2796 // Check whether this object references another object. |
2735 bool JSObject::ReferencesObject(Object* obj) { | 2797 bool JSObject::ReferencesObject(Object* obj) { |
| 2798 Heap* heap = GetHeap(); |
2736 AssertNoAllocation no_alloc; | 2799 AssertNoAllocation no_alloc; |
2737 | 2800 |
2738 // Is the object the constructor for this object? | 2801 // Is the object the constructor for this object? |
2739 if (map()->constructor() == obj) { | 2802 if (map()->constructor() == obj) { |
2740 return true; | 2803 return true; |
2741 } | 2804 } |
2742 | 2805 |
2743 // Is the object the prototype for this object? | 2806 // Is the object the prototype for this object? |
2744 if (map()->prototype() == obj) { | 2807 if (map()->prototype() == obj) { |
2745 return true; | 2808 return true; |
2746 } | 2809 } |
2747 | 2810 |
2748 // Check if the object is among the named properties. | 2811 // Check if the object is among the named properties. |
2749 Object* key = SlowReverseLookup(obj); | 2812 Object* key = SlowReverseLookup(obj); |
2750 if (key != Heap::undefined_value()) { | 2813 if (!key->IsUndefined()) { |
2751 return true; | 2814 return true; |
2752 } | 2815 } |
2753 | 2816 |
2754 // Check if the object is among the indexed properties. | 2817 // Check if the object is among the indexed properties. |
2755 switch (GetElementsKind()) { | 2818 switch (GetElementsKind()) { |
2756 case EXTERNAL_PIXEL_ELEMENTS: | 2819 case EXTERNAL_PIXEL_ELEMENTS: |
2757 case EXTERNAL_BYTE_ELEMENTS: | 2820 case EXTERNAL_BYTE_ELEMENTS: |
2758 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 2821 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
2759 case EXTERNAL_SHORT_ELEMENTS: | 2822 case EXTERNAL_SHORT_ELEMENTS: |
2760 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 2823 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
(...skipping 10 matching lines...) Expand all Loading... |
2771 for (int i = 0; i < length; i++) { | 2834 for (int i = 0; i < length; i++) { |
2772 Object* element = FixedArray::cast(elements())->get(i); | 2835 Object* element = FixedArray::cast(elements())->get(i); |
2773 if (!element->IsTheHole() && element == obj) { | 2836 if (!element->IsTheHole() && element == obj) { |
2774 return true; | 2837 return true; |
2775 } | 2838 } |
2776 } | 2839 } |
2777 break; | 2840 break; |
2778 } | 2841 } |
2779 case DICTIONARY_ELEMENTS: { | 2842 case DICTIONARY_ELEMENTS: { |
2780 key = element_dictionary()->SlowReverseLookup(obj); | 2843 key = element_dictionary()->SlowReverseLookup(obj); |
2781 if (key != Heap::undefined_value()) { | 2844 if (!key->IsUndefined()) { |
2782 return true; | 2845 return true; |
2783 } | 2846 } |
2784 break; | 2847 break; |
2785 } | 2848 } |
2786 default: | 2849 default: |
2787 UNREACHABLE(); | 2850 UNREACHABLE(); |
2788 break; | 2851 break; |
2789 } | 2852 } |
2790 | 2853 |
2791 // For functions check the context. | 2854 // For functions check the context. |
2792 if (IsJSFunction()) { | 2855 if (IsJSFunction()) { |
2793 // Get the constructor function for arguments array. | 2856 // Get the constructor function for arguments array. |
2794 JSObject* arguments_boilerplate = | 2857 JSObject* arguments_boilerplate = |
2795 Top::context()->global_context()->arguments_boilerplate(); | 2858 heap->isolate()->context()->global_context()-> |
| 2859 arguments_boilerplate(); |
2796 JSFunction* arguments_function = | 2860 JSFunction* arguments_function = |
2797 JSFunction::cast(arguments_boilerplate->map()->constructor()); | 2861 JSFunction::cast(arguments_boilerplate->map()->constructor()); |
2798 | 2862 |
2799 // Get the context and don't check if it is the global context. | 2863 // Get the context and don't check if it is the global context. |
2800 JSFunction* f = JSFunction::cast(this); | 2864 JSFunction* f = JSFunction::cast(this); |
2801 Context* context = f->context(); | 2865 Context* context = f->context(); |
2802 if (context->IsGlobalContext()) { | 2866 if (context->IsGlobalContext()) { |
2803 return false; | 2867 return false; |
2804 } | 2868 } |
2805 | 2869 |
(...skipping 18 matching lines...) Expand all Loading... |
2824 return context->extension()->ReferencesObject(obj); | 2888 return context->extension()->ReferencesObject(obj); |
2825 } | 2889 } |
2826 } | 2890 } |
2827 | 2891 |
2828 // No references to object. | 2892 // No references to object. |
2829 return false; | 2893 return false; |
2830 } | 2894 } |
2831 | 2895 |
2832 | 2896 |
2833 MaybeObject* JSObject::PreventExtensions() { | 2897 MaybeObject* JSObject::PreventExtensions() { |
| 2898 Isolate* isolate = GetIsolate(); |
2834 if (IsAccessCheckNeeded() && | 2899 if (IsAccessCheckNeeded() && |
2835 !Top::MayNamedAccess(this, Heap::undefined_value(), v8::ACCESS_KEYS)) { | 2900 !isolate->MayNamedAccess(this, |
2836 Top::ReportFailedAccessCheck(this, v8::ACCESS_KEYS); | 2901 isolate->heap()->undefined_value(), |
2837 return Heap::false_value(); | 2902 v8::ACCESS_KEYS)) { |
| 2903 isolate->ReportFailedAccessCheck(this, v8::ACCESS_KEYS); |
| 2904 return isolate->heap()->false_value(); |
2838 } | 2905 } |
2839 | 2906 |
2840 if (IsJSGlobalProxy()) { | 2907 if (IsJSGlobalProxy()) { |
2841 Object* proto = GetPrototype(); | 2908 Object* proto = GetPrototype(); |
2842 if (proto->IsNull()) return this; | 2909 if (proto->IsNull()) return this; |
2843 ASSERT(proto->IsJSGlobalObject()); | 2910 ASSERT(proto->IsJSGlobalObject()); |
2844 return JSObject::cast(proto)->PreventExtensions(); | 2911 return JSObject::cast(proto)->PreventExtensions(); |
2845 } | 2912 } |
2846 | 2913 |
2847 // If there are fast elements we normalize. | 2914 // If there are fast elements we normalize. |
(...skipping 18 matching lines...) Expand all Loading... |
2866 return new_map; | 2933 return new_map; |
2867 } | 2934 } |
2868 | 2935 |
2869 | 2936 |
2870 // Tests for the fast common case for property enumeration: | 2937 // Tests for the fast common case for property enumeration: |
2871 // - This object and all prototypes has an enum cache (which means that it has | 2938 // - This object and all prototypes has an enum cache (which means that it has |
2872 // no interceptors and needs no access checks). | 2939 // no interceptors and needs no access checks). |
2873 // - This object has no elements. | 2940 // - This object has no elements. |
2874 // - No prototype has enumerable properties/elements. | 2941 // - No prototype has enumerable properties/elements. |
2875 bool JSObject::IsSimpleEnum() { | 2942 bool JSObject::IsSimpleEnum() { |
| 2943 Heap* heap = GetHeap(); |
2876 for (Object* o = this; | 2944 for (Object* o = this; |
2877 o != Heap::null_value(); | 2945 o != heap->null_value(); |
2878 o = JSObject::cast(o)->GetPrototype()) { | 2946 o = JSObject::cast(o)->GetPrototype()) { |
2879 JSObject* curr = JSObject::cast(o); | 2947 JSObject* curr = JSObject::cast(o); |
2880 if (!curr->map()->instance_descriptors()->HasEnumCache()) return false; | 2948 if (!curr->map()->instance_descriptors()->HasEnumCache()) return false; |
2881 ASSERT(!curr->HasNamedInterceptor()); | 2949 ASSERT(!curr->HasNamedInterceptor()); |
2882 ASSERT(!curr->HasIndexedInterceptor()); | 2950 ASSERT(!curr->HasIndexedInterceptor()); |
2883 ASSERT(!curr->IsAccessCheckNeeded()); | 2951 ASSERT(!curr->IsAccessCheckNeeded()); |
2884 if (curr->NumberOfEnumElements() > 0) return false; | 2952 if (curr->NumberOfEnumElements() > 0) return false; |
2885 if (curr != this) { | 2953 if (curr != this) { |
2886 FixedArray* curr_fixed_array = | 2954 FixedArray* curr_fixed_array = |
2887 FixedArray::cast(curr->map()->instance_descriptors()->GetEnumCache()); | 2955 FixedArray::cast(curr->map()->instance_descriptors()->GetEnumCache()); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2933 return descs->GetCallbacks(i); | 3001 return descs->GetCallbacks(i); |
2934 } | 3002 } |
2935 } | 3003 } |
2936 return NULL; | 3004 return NULL; |
2937 } | 3005 } |
2938 | 3006 |
2939 | 3007 |
2940 void JSObject::LocalLookup(String* name, LookupResult* result) { | 3008 void JSObject::LocalLookup(String* name, LookupResult* result) { |
2941 ASSERT(name->IsString()); | 3009 ASSERT(name->IsString()); |
2942 | 3010 |
| 3011 Heap* heap = GetHeap(); |
| 3012 |
2943 if (IsJSGlobalProxy()) { | 3013 if (IsJSGlobalProxy()) { |
2944 Object* proto = GetPrototype(); | 3014 Object* proto = GetPrototype(); |
2945 if (proto->IsNull()) return result->NotFound(); | 3015 if (proto->IsNull()) return result->NotFound(); |
2946 ASSERT(proto->IsJSGlobalObject()); | 3016 ASSERT(proto->IsJSGlobalObject()); |
2947 return JSObject::cast(proto)->LocalLookup(name, result); | 3017 return JSObject::cast(proto)->LocalLookup(name, result); |
2948 } | 3018 } |
2949 | 3019 |
2950 // Do not use inline caching if the object is a non-global object | 3020 // Do not use inline caching if the object is a non-global object |
2951 // that requires access checks. | 3021 // that requires access checks. |
2952 if (!IsJSGlobalProxy() && IsAccessCheckNeeded()) { | 3022 if (!IsJSGlobalProxy() && IsAccessCheckNeeded()) { |
2953 result->DisallowCaching(); | 3023 result->DisallowCaching(); |
2954 } | 3024 } |
2955 | 3025 |
2956 // Check __proto__ before interceptor. | 3026 // Check __proto__ before interceptor. |
2957 if (name->Equals(Heap::Proto_symbol()) && !IsJSContextExtensionObject()) { | 3027 if (name->Equals(heap->Proto_symbol()) && |
| 3028 !IsJSContextExtensionObject()) { |
2958 result->ConstantResult(this); | 3029 result->ConstantResult(this); |
2959 return; | 3030 return; |
2960 } | 3031 } |
2961 | 3032 |
2962 // Check for lookup interceptor except when bootstrapping. | 3033 // Check for lookup interceptor except when bootstrapping. |
2963 if (HasNamedInterceptor() && !Bootstrapper::IsActive()) { | 3034 if (HasNamedInterceptor() && !heap->isolate()->bootstrapper()->IsActive()) { |
2964 result->InterceptorResult(this); | 3035 result->InterceptorResult(this); |
2965 return; | 3036 return; |
2966 } | 3037 } |
2967 | 3038 |
2968 LocalLookupRealNamedProperty(name, result); | 3039 LocalLookupRealNamedProperty(name, result); |
2969 } | 3040 } |
2970 | 3041 |
2971 | 3042 |
2972 void JSObject::Lookup(String* name, LookupResult* result) { | 3043 void JSObject::Lookup(String* name, LookupResult* result) { |
2973 // Ecma-262 3rd 8.6.2.4 | 3044 // Ecma-262 3rd 8.6.2.4 |
| 3045 Heap* heap = GetHeap(); |
2974 for (Object* current = this; | 3046 for (Object* current = this; |
2975 current != Heap::null_value(); | 3047 current != heap->null_value(); |
2976 current = JSObject::cast(current)->GetPrototype()) { | 3048 current = JSObject::cast(current)->GetPrototype()) { |
2977 JSObject::cast(current)->LocalLookup(name, result); | 3049 JSObject::cast(current)->LocalLookup(name, result); |
2978 if (result->IsProperty()) return; | 3050 if (result->IsProperty()) return; |
2979 } | 3051 } |
2980 result->NotFound(); | 3052 result->NotFound(); |
2981 } | 3053 } |
2982 | 3054 |
2983 | 3055 |
2984 // Search object and it's prototype chain for callback properties. | 3056 // Search object and it's prototype chain for callback properties. |
2985 void JSObject::LookupCallback(String* name, LookupResult* result) { | 3057 void JSObject::LookupCallback(String* name, LookupResult* result) { |
| 3058 Heap* heap = GetHeap(); |
2986 for (Object* current = this; | 3059 for (Object* current = this; |
2987 current != Heap::null_value(); | 3060 current != heap->null_value(); |
2988 current = JSObject::cast(current)->GetPrototype()) { | 3061 current = JSObject::cast(current)->GetPrototype()) { |
2989 JSObject::cast(current)->LocalLookupRealNamedProperty(name, result); | 3062 JSObject::cast(current)->LocalLookupRealNamedProperty(name, result); |
2990 if (result->IsProperty() && result->type() == CALLBACKS) return; | 3063 if (result->IsProperty() && result->type() == CALLBACKS) return; |
2991 } | 3064 } |
2992 result->NotFound(); | 3065 result->NotFound(); |
2993 } | 3066 } |
2994 | 3067 |
2995 | 3068 |
2996 MaybeObject* JSObject::DefineGetterSetter(String* name, | 3069 MaybeObject* JSObject::DefineGetterSetter(String* name, |
2997 PropertyAttributes attributes) { | 3070 PropertyAttributes attributes) { |
| 3071 Heap* heap = GetHeap(); |
2998 // Make sure that the top context does not change when doing callbacks or | 3072 // Make sure that the top context does not change when doing callbacks or |
2999 // interceptor calls. | 3073 // interceptor calls. |
3000 AssertNoContextChange ncc; | 3074 AssertNoContextChange ncc; |
3001 | 3075 |
3002 // Try to flatten before operating on the string. | 3076 // Try to flatten before operating on the string. |
3003 name->TryFlatten(); | 3077 name->TryFlatten(); |
3004 | 3078 |
3005 if (!CanSetCallback(name)) { | 3079 if (!CanSetCallback(name)) { |
3006 return Heap::undefined_value(); | 3080 return heap->undefined_value(); |
3007 } | 3081 } |
3008 | 3082 |
3009 uint32_t index = 0; | 3083 uint32_t index = 0; |
3010 bool is_element = name->AsArrayIndex(&index); | 3084 bool is_element = name->AsArrayIndex(&index); |
3011 | 3085 |
3012 if (is_element) { | 3086 if (is_element) { |
3013 switch (GetElementsKind()) { | 3087 switch (GetElementsKind()) { |
3014 case FAST_ELEMENTS: | 3088 case FAST_ELEMENTS: |
3015 break; | 3089 break; |
3016 case EXTERNAL_PIXEL_ELEMENTS: | 3090 case EXTERNAL_PIXEL_ELEMENTS: |
3017 case EXTERNAL_BYTE_ELEMENTS: | 3091 case EXTERNAL_BYTE_ELEMENTS: |
3018 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 3092 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
3019 case EXTERNAL_SHORT_ELEMENTS: | 3093 case EXTERNAL_SHORT_ELEMENTS: |
3020 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 3094 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
3021 case EXTERNAL_INT_ELEMENTS: | 3095 case EXTERNAL_INT_ELEMENTS: |
3022 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 3096 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
3023 case EXTERNAL_FLOAT_ELEMENTS: | 3097 case EXTERNAL_FLOAT_ELEMENTS: |
3024 // Ignore getters and setters on pixel and external array | 3098 // Ignore getters and setters on pixel and external array |
3025 // elements. | 3099 // elements. |
3026 return Heap::undefined_value(); | 3100 return heap->undefined_value(); |
3027 case DICTIONARY_ELEMENTS: { | 3101 case DICTIONARY_ELEMENTS: { |
3028 // Lookup the index. | 3102 // Lookup the index. |
3029 NumberDictionary* dictionary = element_dictionary(); | 3103 NumberDictionary* dictionary = element_dictionary(); |
3030 int entry = dictionary->FindEntry(index); | 3104 int entry = dictionary->FindEntry(index); |
3031 if (entry != NumberDictionary::kNotFound) { | 3105 if (entry != NumberDictionary::kNotFound) { |
3032 Object* result = dictionary->ValueAt(entry); | 3106 Object* result = dictionary->ValueAt(entry); |
3033 PropertyDetails details = dictionary->DetailsAt(entry); | 3107 PropertyDetails details = dictionary->DetailsAt(entry); |
3034 if (details.IsReadOnly()) return Heap::undefined_value(); | 3108 if (details.IsReadOnly()) return heap->undefined_value(); |
3035 if (details.type() == CALLBACKS) { | 3109 if (details.type() == CALLBACKS) { |
3036 if (result->IsFixedArray()) { | 3110 if (result->IsFixedArray()) { |
3037 return result; | 3111 return result; |
3038 } | 3112 } |
3039 // Otherwise allow to override it. | 3113 // Otherwise allow to override it. |
3040 } | 3114 } |
3041 } | 3115 } |
3042 break; | 3116 break; |
3043 } | 3117 } |
3044 default: | 3118 default: |
3045 UNREACHABLE(); | 3119 UNREACHABLE(); |
3046 break; | 3120 break; |
3047 } | 3121 } |
3048 } else { | 3122 } else { |
3049 // Lookup the name. | 3123 // Lookup the name. |
3050 LookupResult result; | 3124 LookupResult result; |
3051 LocalLookup(name, &result); | 3125 LocalLookup(name, &result); |
3052 if (result.IsProperty()) { | 3126 if (result.IsProperty()) { |
3053 if (result.IsReadOnly()) return Heap::undefined_value(); | 3127 if (result.IsReadOnly()) return heap->undefined_value(); |
3054 if (result.type() == CALLBACKS) { | 3128 if (result.type() == CALLBACKS) { |
3055 Object* obj = result.GetCallbackObject(); | 3129 Object* obj = result.GetCallbackObject(); |
3056 // Need to preserve old getters/setters. | 3130 // Need to preserve old getters/setters. |
3057 if (obj->IsFixedArray()) { | 3131 if (obj->IsFixedArray()) { |
3058 // Use set to update attributes. | 3132 // Use set to update attributes. |
3059 return SetPropertyCallback(name, obj, attributes); | 3133 return SetPropertyCallback(name, obj, attributes); |
3060 } | 3134 } |
3061 } | 3135 } |
3062 } | 3136 } |
3063 } | 3137 } |
3064 | 3138 |
3065 // Allocate the fixed array to hold getter and setter. | 3139 // Allocate the fixed array to hold getter and setter. |
3066 Object* structure; | 3140 Object* structure; |
3067 { MaybeObject* maybe_structure = Heap::AllocateFixedArray(2, TENURED); | 3141 { MaybeObject* maybe_structure = heap->AllocateFixedArray(2, TENURED); |
3068 if (!maybe_structure->ToObject(&structure)) return maybe_structure; | 3142 if (!maybe_structure->ToObject(&structure)) return maybe_structure; |
3069 } | 3143 } |
3070 | 3144 |
3071 if (is_element) { | 3145 if (is_element) { |
3072 return SetElementCallback(index, structure, attributes); | 3146 return SetElementCallback(index, structure, attributes); |
3073 } else { | 3147 } else { |
3074 return SetPropertyCallback(name, structure, attributes); | 3148 return SetPropertyCallback(name, structure, attributes); |
3075 } | 3149 } |
3076 } | 3150 } |
3077 | 3151 |
3078 | 3152 |
3079 bool JSObject::CanSetCallback(String* name) { | 3153 bool JSObject::CanSetCallback(String* name) { |
3080 ASSERT(!IsAccessCheckNeeded() | 3154 ASSERT(!IsAccessCheckNeeded() |
3081 || Top::MayNamedAccess(this, name, v8::ACCESS_SET)); | 3155 || Isolate::Current()->MayNamedAccess(this, name, v8::ACCESS_SET)); |
3082 | 3156 |
3083 // Check if there is an API defined callback object which prohibits | 3157 // Check if there is an API defined callback object which prohibits |
3084 // callback overwriting in this object or it's prototype chain. | 3158 // callback overwriting in this object or it's prototype chain. |
3085 // This mechanism is needed for instance in a browser setting, where | 3159 // This mechanism is needed for instance in a browser setting, where |
3086 // certain accessors such as window.location should not be allowed | 3160 // certain accessors such as window.location should not be allowed |
3087 // to be overwritten because allowing overwriting could potentially | 3161 // to be overwritten because allowing overwriting could potentially |
3088 // cause security problems. | 3162 // cause security problems. |
3089 LookupResult callback_result; | 3163 LookupResult callback_result; |
3090 LookupCallback(name, &callback_result); | 3164 LookupCallback(name, &callback_result); |
3091 if (callback_result.IsProperty()) { | 3165 if (callback_result.IsProperty()) { |
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3168 } | 3242 } |
3169 } | 3243 } |
3170 return result; | 3244 return result; |
3171 } | 3245 } |
3172 | 3246 |
3173 MaybeObject* JSObject::DefineAccessor(String* name, | 3247 MaybeObject* JSObject::DefineAccessor(String* name, |
3174 bool is_getter, | 3248 bool is_getter, |
3175 Object* fun, | 3249 Object* fun, |
3176 PropertyAttributes attributes) { | 3250 PropertyAttributes attributes) { |
3177 ASSERT(fun->IsJSFunction() || fun->IsUndefined()); | 3251 ASSERT(fun->IsJSFunction() || fun->IsUndefined()); |
| 3252 Isolate* isolate = GetIsolate(); |
3178 // Check access rights if needed. | 3253 // Check access rights if needed. |
3179 if (IsAccessCheckNeeded() && | 3254 if (IsAccessCheckNeeded() && |
3180 !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) { | 3255 !isolate->MayNamedAccess(this, name, v8::ACCESS_SET)) { |
3181 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); | 3256 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); |
3182 return Heap::undefined_value(); | 3257 return isolate->heap()->undefined_value(); |
3183 } | 3258 } |
3184 | 3259 |
3185 if (IsJSGlobalProxy()) { | 3260 if (IsJSGlobalProxy()) { |
3186 Object* proto = GetPrototype(); | 3261 Object* proto = GetPrototype(); |
3187 if (proto->IsNull()) return this; | 3262 if (proto->IsNull()) return this; |
3188 ASSERT(proto->IsJSGlobalObject()); | 3263 ASSERT(proto->IsJSGlobalObject()); |
3189 return JSObject::cast(proto)->DefineAccessor(name, is_getter, | 3264 return JSObject::cast(proto)->DefineAccessor(name, is_getter, |
3190 fun, attributes); | 3265 fun, attributes); |
3191 } | 3266 } |
3192 | 3267 |
3193 Object* array; | 3268 Object* array; |
3194 { MaybeObject* maybe_array = DefineGetterSetter(name, attributes); | 3269 { MaybeObject* maybe_array = DefineGetterSetter(name, attributes); |
3195 if (!maybe_array->ToObject(&array)) return maybe_array; | 3270 if (!maybe_array->ToObject(&array)) return maybe_array; |
3196 } | 3271 } |
3197 if (array->IsUndefined()) return array; | 3272 if (array->IsUndefined()) return array; |
3198 FixedArray::cast(array)->set(is_getter ? 0 : 1, fun); | 3273 FixedArray::cast(array)->set(is_getter ? 0 : 1, fun); |
3199 return this; | 3274 return this; |
3200 } | 3275 } |
3201 | 3276 |
3202 | 3277 |
3203 MaybeObject* JSObject::DefineAccessor(AccessorInfo* info) { | 3278 MaybeObject* JSObject::DefineAccessor(AccessorInfo* info) { |
| 3279 Isolate* isolate = GetIsolate(); |
3204 String* name = String::cast(info->name()); | 3280 String* name = String::cast(info->name()); |
3205 // Check access rights if needed. | 3281 // Check access rights if needed. |
3206 if (IsAccessCheckNeeded() && | 3282 if (IsAccessCheckNeeded() && |
3207 !Top::MayNamedAccess(this, name, v8::ACCESS_SET)) { | 3283 !isolate->MayNamedAccess(this, name, v8::ACCESS_SET)) { |
3208 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); | 3284 isolate->ReportFailedAccessCheck(this, v8::ACCESS_SET); |
3209 return Heap::undefined_value(); | 3285 return isolate->heap()->undefined_value(); |
3210 } | 3286 } |
3211 | 3287 |
3212 if (IsJSGlobalProxy()) { | 3288 if (IsJSGlobalProxy()) { |
3213 Object* proto = GetPrototype(); | 3289 Object* proto = GetPrototype(); |
3214 if (proto->IsNull()) return this; | 3290 if (proto->IsNull()) return this; |
3215 ASSERT(proto->IsJSGlobalObject()); | 3291 ASSERT(proto->IsJSGlobalObject()); |
3216 return JSObject::cast(proto)->DefineAccessor(info); | 3292 return JSObject::cast(proto)->DefineAccessor(info); |
3217 } | 3293 } |
3218 | 3294 |
3219 // Make sure that the top context does not change when doing callbacks or | 3295 // Make sure that the top context does not change when doing callbacks or |
3220 // interceptor calls. | 3296 // interceptor calls. |
3221 AssertNoContextChange ncc; | 3297 AssertNoContextChange ncc; |
3222 | 3298 |
3223 // Try to flatten before operating on the string. | 3299 // Try to flatten before operating on the string. |
3224 name->TryFlatten(); | 3300 name->TryFlatten(); |
3225 | 3301 |
3226 if (!CanSetCallback(name)) { | 3302 if (!CanSetCallback(name)) { |
3227 return Heap::undefined_value(); | 3303 return isolate->heap()->undefined_value(); |
3228 } | 3304 } |
3229 | 3305 |
3230 uint32_t index = 0; | 3306 uint32_t index = 0; |
3231 bool is_element = name->AsArrayIndex(&index); | 3307 bool is_element = name->AsArrayIndex(&index); |
3232 | 3308 |
3233 if (is_element) { | 3309 if (is_element) { |
3234 if (IsJSArray()) return Heap::undefined_value(); | 3310 if (IsJSArray()) return isolate->heap()->undefined_value(); |
3235 | 3311 |
3236 // Accessors overwrite previous callbacks (cf. with getters/setters). | 3312 // Accessors overwrite previous callbacks (cf. with getters/setters). |
3237 switch (GetElementsKind()) { | 3313 switch (GetElementsKind()) { |
3238 case FAST_ELEMENTS: | 3314 case FAST_ELEMENTS: |
3239 break; | 3315 break; |
3240 case EXTERNAL_PIXEL_ELEMENTS: | 3316 case EXTERNAL_PIXEL_ELEMENTS: |
3241 case EXTERNAL_BYTE_ELEMENTS: | 3317 case EXTERNAL_BYTE_ELEMENTS: |
3242 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 3318 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
3243 case EXTERNAL_SHORT_ELEMENTS: | 3319 case EXTERNAL_SHORT_ELEMENTS: |
3244 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 3320 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
3245 case EXTERNAL_INT_ELEMENTS: | 3321 case EXTERNAL_INT_ELEMENTS: |
3246 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 3322 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
3247 case EXTERNAL_FLOAT_ELEMENTS: | 3323 case EXTERNAL_FLOAT_ELEMENTS: |
3248 // Ignore getters and setters on pixel and external array | 3324 // Ignore getters and setters on pixel and external array |
3249 // elements. | 3325 // elements. |
3250 return Heap::undefined_value(); | 3326 return isolate->heap()->undefined_value(); |
3251 case DICTIONARY_ELEMENTS: | 3327 case DICTIONARY_ELEMENTS: |
3252 break; | 3328 break; |
3253 default: | 3329 default: |
3254 UNREACHABLE(); | 3330 UNREACHABLE(); |
3255 break; | 3331 break; |
3256 } | 3332 } |
3257 | 3333 |
3258 Object* ok; | 3334 Object* ok; |
3259 { MaybeObject* maybe_ok = | 3335 { MaybeObject* maybe_ok = |
3260 SetElementCallback(index, info, info->property_attributes()); | 3336 SetElementCallback(index, info, info->property_attributes()); |
3261 if (!maybe_ok->ToObject(&ok)) return maybe_ok; | 3337 if (!maybe_ok->ToObject(&ok)) return maybe_ok; |
3262 } | 3338 } |
3263 } else { | 3339 } else { |
3264 // Lookup the name. | 3340 // Lookup the name. |
3265 LookupResult result; | 3341 LookupResult result; |
3266 LocalLookup(name, &result); | 3342 LocalLookup(name, &result); |
3267 // ES5 forbids turning a property into an accessor if it's not | 3343 // ES5 forbids turning a property into an accessor if it's not |
3268 // configurable (that is IsDontDelete in ES3 and v8), see 8.6.1 (Table 5). | 3344 // configurable (that is IsDontDelete in ES3 and v8), see 8.6.1 (Table 5). |
3269 if (result.IsProperty() && (result.IsReadOnly() || result.IsDontDelete())) { | 3345 if (result.IsProperty() && (result.IsReadOnly() || result.IsDontDelete())) { |
3270 return Heap::undefined_value(); | 3346 return isolate->heap()->undefined_value(); |
3271 } | 3347 } |
3272 Object* ok; | 3348 Object* ok; |
3273 { MaybeObject* maybe_ok = | 3349 { MaybeObject* maybe_ok = |
3274 SetPropertyCallback(name, info, info->property_attributes()); | 3350 SetPropertyCallback(name, info, info->property_attributes()); |
3275 if (!maybe_ok->ToObject(&ok)) return maybe_ok; | 3351 if (!maybe_ok->ToObject(&ok)) return maybe_ok; |
3276 } | 3352 } |
3277 } | 3353 } |
3278 | 3354 |
3279 return this; | 3355 return this; |
3280 } | 3356 } |
3281 | 3357 |
3282 | 3358 |
3283 Object* JSObject::LookupAccessor(String* name, bool is_getter) { | 3359 Object* JSObject::LookupAccessor(String* name, bool is_getter) { |
| 3360 Heap* heap = GetHeap(); |
| 3361 |
3284 // Make sure that the top context does not change when doing callbacks or | 3362 // Make sure that the top context does not change when doing callbacks or |
3285 // interceptor calls. | 3363 // interceptor calls. |
3286 AssertNoContextChange ncc; | 3364 AssertNoContextChange ncc; |
3287 | 3365 |
3288 // Check access rights if needed. | 3366 // Check access rights if needed. |
3289 if (IsAccessCheckNeeded() && | 3367 if (IsAccessCheckNeeded() && |
3290 !Top::MayNamedAccess(this, name, v8::ACCESS_HAS)) { | 3368 !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_HAS)) { |
3291 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 3369 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
3292 return Heap::undefined_value(); | 3370 return heap->undefined_value(); |
3293 } | 3371 } |
3294 | 3372 |
3295 // Make the lookup and include prototypes. | 3373 // Make the lookup and include prototypes. |
3296 int accessor_index = is_getter ? kGetterIndex : kSetterIndex; | 3374 int accessor_index = is_getter ? kGetterIndex : kSetterIndex; |
3297 uint32_t index = 0; | 3375 uint32_t index = 0; |
3298 if (name->AsArrayIndex(&index)) { | 3376 if (name->AsArrayIndex(&index)) { |
3299 for (Object* obj = this; | 3377 for (Object* obj = this; |
3300 obj != Heap::null_value(); | 3378 obj != heap->null_value(); |
3301 obj = JSObject::cast(obj)->GetPrototype()) { | 3379 obj = JSObject::cast(obj)->GetPrototype()) { |
3302 JSObject* js_object = JSObject::cast(obj); | 3380 JSObject* js_object = JSObject::cast(obj); |
3303 if (js_object->HasDictionaryElements()) { | 3381 if (js_object->HasDictionaryElements()) { |
3304 NumberDictionary* dictionary = js_object->element_dictionary(); | 3382 NumberDictionary* dictionary = js_object->element_dictionary(); |
3305 int entry = dictionary->FindEntry(index); | 3383 int entry = dictionary->FindEntry(index); |
3306 if (entry != NumberDictionary::kNotFound) { | 3384 if (entry != NumberDictionary::kNotFound) { |
3307 Object* element = dictionary->ValueAt(entry); | 3385 Object* element = dictionary->ValueAt(entry); |
3308 PropertyDetails details = dictionary->DetailsAt(entry); | 3386 PropertyDetails details = dictionary->DetailsAt(entry); |
3309 if (details.type() == CALLBACKS) { | 3387 if (details.type() == CALLBACKS) { |
3310 if (element->IsFixedArray()) { | 3388 if (element->IsFixedArray()) { |
3311 return FixedArray::cast(element)->get(accessor_index); | 3389 return FixedArray::cast(element)->get(accessor_index); |
3312 } | 3390 } |
3313 } | 3391 } |
3314 } | 3392 } |
3315 } | 3393 } |
3316 } | 3394 } |
3317 } else { | 3395 } else { |
3318 for (Object* obj = this; | 3396 for (Object* obj = this; |
3319 obj != Heap::null_value(); | 3397 obj != heap->null_value(); |
3320 obj = JSObject::cast(obj)->GetPrototype()) { | 3398 obj = JSObject::cast(obj)->GetPrototype()) { |
3321 LookupResult result; | 3399 LookupResult result; |
3322 JSObject::cast(obj)->LocalLookup(name, &result); | 3400 JSObject::cast(obj)->LocalLookup(name, &result); |
3323 if (result.IsProperty()) { | 3401 if (result.IsProperty()) { |
3324 if (result.IsReadOnly()) return Heap::undefined_value(); | 3402 if (result.IsReadOnly()) return heap->undefined_value(); |
3325 if (result.type() == CALLBACKS) { | 3403 if (result.type() == CALLBACKS) { |
3326 Object* obj = result.GetCallbackObject(); | 3404 Object* obj = result.GetCallbackObject(); |
3327 if (obj->IsFixedArray()) { | 3405 if (obj->IsFixedArray()) { |
3328 return FixedArray::cast(obj)->get(accessor_index); | 3406 return FixedArray::cast(obj)->get(accessor_index); |
3329 } | 3407 } |
3330 } | 3408 } |
3331 } | 3409 } |
3332 } | 3410 } |
3333 } | 3411 } |
3334 return Heap::undefined_value(); | 3412 return heap->undefined_value(); |
3335 } | 3413 } |
3336 | 3414 |
3337 | 3415 |
3338 Object* JSObject::SlowReverseLookup(Object* value) { | 3416 Object* JSObject::SlowReverseLookup(Object* value) { |
| 3417 Heap* heap = GetHeap(); |
3339 if (HasFastProperties()) { | 3418 if (HasFastProperties()) { |
3340 DescriptorArray* descs = map()->instance_descriptors(); | 3419 DescriptorArray* descs = map()->instance_descriptors(); |
3341 for (int i = 0; i < descs->number_of_descriptors(); i++) { | 3420 for (int i = 0; i < descs->number_of_descriptors(); i++) { |
3342 if (descs->GetType(i) == FIELD) { | 3421 if (descs->GetType(i) == FIELD) { |
3343 if (FastPropertyAt(descs->GetFieldIndex(i)) == value) { | 3422 if (FastPropertyAt(descs->GetFieldIndex(i)) == value) { |
3344 return descs->GetKey(i); | 3423 return descs->GetKey(i); |
3345 } | 3424 } |
3346 } else if (descs->GetType(i) == CONSTANT_FUNCTION) { | 3425 } else if (descs->GetType(i) == CONSTANT_FUNCTION) { |
3347 if (descs->GetConstantFunction(i) == value) { | 3426 if (descs->GetConstantFunction(i) == value) { |
3348 return descs->GetKey(i); | 3427 return descs->GetKey(i); |
3349 } | 3428 } |
3350 } | 3429 } |
3351 } | 3430 } |
3352 return Heap::undefined_value(); | 3431 return heap->undefined_value(); |
3353 } else { | 3432 } else { |
3354 return property_dictionary()->SlowReverseLookup(value); | 3433 return property_dictionary()->SlowReverseLookup(value); |
3355 } | 3434 } |
3356 } | 3435 } |
3357 | 3436 |
3358 | 3437 |
3359 MaybeObject* Map::CopyDropDescriptors() { | 3438 MaybeObject* Map::CopyDropDescriptors() { |
| 3439 Heap* heap = GetHeap(); |
3360 Object* result; | 3440 Object* result; |
3361 { MaybeObject* maybe_result = | 3441 { MaybeObject* maybe_result = |
3362 Heap::AllocateMap(instance_type(), instance_size()); | 3442 heap->AllocateMap(instance_type(), instance_size()); |
3363 if (!maybe_result->ToObject(&result)) return maybe_result; | 3443 if (!maybe_result->ToObject(&result)) return maybe_result; |
3364 } | 3444 } |
3365 Map::cast(result)->set_prototype(prototype()); | 3445 Map::cast(result)->set_prototype(prototype()); |
3366 Map::cast(result)->set_constructor(constructor()); | 3446 Map::cast(result)->set_constructor(constructor()); |
3367 // Don't copy descriptors, so map transitions always remain a forest. | 3447 // Don't copy descriptors, so map transitions always remain a forest. |
3368 // If we retained the same descriptors we would have two maps | 3448 // If we retained the same descriptors we would have two maps |
3369 // pointing to the same transition which is bad because the garbage | 3449 // pointing to the same transition which is bad because the garbage |
3370 // collector relies on being able to reverse pointers from transitions | 3450 // collector relies on being able to reverse pointers from transitions |
3371 // to maps. If properties need to be retained use CopyDropTransitions. | 3451 // to maps. If properties need to be retained use CopyDropTransitions. |
3372 Map::cast(result)->set_instance_descriptors(Heap::empty_descriptor_array()); | 3452 Map::cast(result)->set_instance_descriptors( |
| 3453 heap->empty_descriptor_array()); |
3373 // Please note instance_type and instance_size are set when allocated. | 3454 // Please note instance_type and instance_size are set when allocated. |
3374 Map::cast(result)->set_inobject_properties(inobject_properties()); | 3455 Map::cast(result)->set_inobject_properties(inobject_properties()); |
3375 Map::cast(result)->set_unused_property_fields(unused_property_fields()); | 3456 Map::cast(result)->set_unused_property_fields(unused_property_fields()); |
3376 | 3457 |
3377 // If the map has pre-allocated properties always start out with a descriptor | 3458 // If the map has pre-allocated properties always start out with a descriptor |
3378 // array describing these properties. | 3459 // array describing these properties. |
3379 if (pre_allocated_property_fields() > 0) { | 3460 if (pre_allocated_property_fields() > 0) { |
3380 ASSERT(constructor()->IsJSFunction()); | 3461 ASSERT(constructor()->IsJSFunction()); |
3381 JSFunction* ctor = JSFunction::cast(constructor()); | 3462 JSFunction* ctor = JSFunction::cast(constructor()); |
3382 Object* descriptors; | 3463 Object* descriptors; |
3383 { MaybeObject* maybe_descriptors = | 3464 { MaybeObject* maybe_descriptors = |
3384 ctor->initial_map()->instance_descriptors()->RemoveTransitions(); | 3465 ctor->initial_map()->instance_descriptors()->RemoveTransitions(); |
3385 if (!maybe_descriptors->ToObject(&descriptors)) return maybe_descriptors; | 3466 if (!maybe_descriptors->ToObject(&descriptors)) return maybe_descriptors; |
3386 } | 3467 } |
3387 Map::cast(result)->set_instance_descriptors( | 3468 Map::cast(result)->set_instance_descriptors( |
3388 DescriptorArray::cast(descriptors)); | 3469 DescriptorArray::cast(descriptors)); |
3389 Map::cast(result)->set_pre_allocated_property_fields( | 3470 Map::cast(result)->set_pre_allocated_property_fields( |
3390 pre_allocated_property_fields()); | 3471 pre_allocated_property_fields()); |
3391 } | 3472 } |
3392 Map::cast(result)->set_bit_field(bit_field()); | 3473 Map::cast(result)->set_bit_field(bit_field()); |
3393 Map::cast(result)->set_bit_field2(bit_field2()); | 3474 Map::cast(result)->set_bit_field2(bit_field2()); |
3394 Map::cast(result)->set_is_shared(false); | 3475 Map::cast(result)->set_is_shared(false); |
3395 Map::cast(result)->ClearCodeCache(); | 3476 Map::cast(result)->ClearCodeCache(heap); |
3396 return result; | 3477 return result; |
3397 } | 3478 } |
3398 | 3479 |
3399 | 3480 |
3400 MaybeObject* Map::CopyNormalized(PropertyNormalizationMode mode, | 3481 MaybeObject* Map::CopyNormalized(PropertyNormalizationMode mode, |
3401 NormalizedMapSharingMode sharing) { | 3482 NormalizedMapSharingMode sharing) { |
3402 int new_instance_size = instance_size(); | 3483 int new_instance_size = instance_size(); |
3403 if (mode == CLEAR_INOBJECT_PROPERTIES) { | 3484 if (mode == CLEAR_INOBJECT_PROPERTIES) { |
3404 new_instance_size -= inobject_properties() * kPointerSize; | 3485 new_instance_size -= inobject_properties() * kPointerSize; |
3405 } | 3486 } |
3406 | 3487 |
3407 Object* result; | 3488 Object* result; |
3408 { MaybeObject* maybe_result = | 3489 { MaybeObject* maybe_result = |
3409 Heap::AllocateMap(instance_type(), new_instance_size); | 3490 GetHeap()->AllocateMap(instance_type(), new_instance_size); |
3410 if (!maybe_result->ToObject(&result)) return maybe_result; | 3491 if (!maybe_result->ToObject(&result)) return maybe_result; |
3411 } | 3492 } |
3412 | 3493 |
3413 if (mode != CLEAR_INOBJECT_PROPERTIES) { | 3494 if (mode != CLEAR_INOBJECT_PROPERTIES) { |
3414 Map::cast(result)->set_inobject_properties(inobject_properties()); | 3495 Map::cast(result)->set_inobject_properties(inobject_properties()); |
3415 } | 3496 } |
3416 | 3497 |
3417 Map::cast(result)->set_prototype(prototype()); | 3498 Map::cast(result)->set_prototype(prototype()); |
3418 Map::cast(result)->set_constructor(constructor()); | 3499 Map::cast(result)->set_constructor(constructor()); |
3419 | 3500 |
(...skipping 24 matching lines...) Expand all Loading... |
3444 } | 3525 } |
3445 cast(new_map)->set_instance_descriptors(DescriptorArray::cast(descriptors)); | 3526 cast(new_map)->set_instance_descriptors(DescriptorArray::cast(descriptors)); |
3446 return new_map; | 3527 return new_map; |
3447 } | 3528 } |
3448 | 3529 |
3449 | 3530 |
3450 MaybeObject* Map::UpdateCodeCache(String* name, Code* code) { | 3531 MaybeObject* Map::UpdateCodeCache(String* name, Code* code) { |
3451 // Allocate the code cache if not present. | 3532 // Allocate the code cache if not present. |
3452 if (code_cache()->IsFixedArray()) { | 3533 if (code_cache()->IsFixedArray()) { |
3453 Object* result; | 3534 Object* result; |
3454 { MaybeObject* maybe_result = Heap::AllocateCodeCache(); | 3535 { MaybeObject* maybe_result = GetHeap()->AllocateCodeCache(); |
3455 if (!maybe_result->ToObject(&result)) return maybe_result; | 3536 if (!maybe_result->ToObject(&result)) return maybe_result; |
3456 } | 3537 } |
3457 set_code_cache(result); | 3538 set_code_cache(result); |
3458 } | 3539 } |
3459 | 3540 |
3460 // Update the code cache. | 3541 // Update the code cache. |
3461 return CodeCache::cast(code_cache())->Update(name, code); | 3542 return CodeCache::cast(code_cache())->Update(name, code); |
3462 } | 3543 } |
3463 | 3544 |
3464 | 3545 |
3465 Object* Map::FindInCodeCache(String* name, Code::Flags flags) { | 3546 Object* Map::FindInCodeCache(String* name, Code::Flags flags) { |
3466 // Do a lookup if a code cache exists. | 3547 // Do a lookup if a code cache exists. |
3467 if (!code_cache()->IsFixedArray()) { | 3548 if (!code_cache()->IsFixedArray()) { |
3468 return CodeCache::cast(code_cache())->Lookup(name, flags); | 3549 return CodeCache::cast(code_cache())->Lookup(name, flags); |
3469 } else { | 3550 } else { |
3470 return Heap::undefined_value(); | 3551 return GetHeap()->undefined_value(); |
3471 } | 3552 } |
3472 } | 3553 } |
3473 | 3554 |
3474 | 3555 |
3475 int Map::IndexInCodeCache(Object* name, Code* code) { | 3556 int Map::IndexInCodeCache(Object* name, Code* code) { |
3476 // Get the internal index if a code cache exists. | 3557 // Get the internal index if a code cache exists. |
3477 if (!code_cache()->IsFixedArray()) { | 3558 if (!code_cache()->IsFixedArray()) { |
3478 return CodeCache::cast(code_cache())->GetIndex(name, code); | 3559 return CodeCache::cast(code_cache())->GetIndex(name, code); |
3479 } | 3560 } |
3480 return -1; | 3561 return -1; |
3481 } | 3562 } |
3482 | 3563 |
3483 | 3564 |
3484 void Map::RemoveFromCodeCache(String* name, Code* code, int index) { | 3565 void Map::RemoveFromCodeCache(String* name, Code* code, int index) { |
3485 // No GC is supposed to happen between a call to IndexInCodeCache and | 3566 // No GC is supposed to happen between a call to IndexInCodeCache and |
3486 // RemoveFromCodeCache so the code cache must be there. | 3567 // RemoveFromCodeCache so the code cache must be there. |
3487 ASSERT(!code_cache()->IsFixedArray()); | 3568 ASSERT(!code_cache()->IsFixedArray()); |
3488 CodeCache::cast(code_cache())->RemoveByIndex(name, code, index); | 3569 CodeCache::cast(code_cache())->RemoveByIndex(name, code, index); |
3489 } | 3570 } |
3490 | 3571 |
3491 | 3572 |
3492 void Map::TraverseTransitionTree(TraverseCallback callback, void* data) { | 3573 void Map::TraverseTransitionTree(TraverseCallback callback, void* data) { |
3493 Map* current = this; | 3574 Map* current = this; |
3494 while (current != Heap::meta_map()) { | 3575 Map* meta_map = heap()->meta_map(); |
| 3576 while (current != meta_map) { |
3495 DescriptorArray* d = reinterpret_cast<DescriptorArray*>( | 3577 DescriptorArray* d = reinterpret_cast<DescriptorArray*>( |
3496 *RawField(current, Map::kInstanceDescriptorsOffset)); | 3578 *RawField(current, Map::kInstanceDescriptorsOffset)); |
3497 if (d == Heap::empty_descriptor_array()) { | 3579 if (d == heap()->empty_descriptor_array()) { |
3498 Map* prev = current->map(); | 3580 Map* prev = current->map(); |
3499 current->set_map(Heap::meta_map()); | 3581 current->set_map(meta_map); |
3500 callback(current, data); | 3582 callback(current, data); |
3501 current = prev; | 3583 current = prev; |
3502 continue; | 3584 continue; |
3503 } | 3585 } |
3504 | 3586 |
3505 FixedArray* contents = reinterpret_cast<FixedArray*>( | 3587 FixedArray* contents = reinterpret_cast<FixedArray*>( |
3506 d->get(DescriptorArray::kContentArrayIndex)); | 3588 d->get(DescriptorArray::kContentArrayIndex)); |
3507 Object** map_or_index_field = RawField(contents, HeapObject::kMapOffset); | 3589 Object** map_or_index_field = RawField(contents, HeapObject::kMapOffset); |
3508 Object* map_or_index = *map_or_index_field; | 3590 Object* map_or_index = *map_or_index_field; |
3509 bool map_done = true; | 3591 bool map_done = true; |
3510 for (int i = map_or_index->IsSmi() ? Smi::cast(map_or_index)->value() : 0; | 3592 for (int i = map_or_index->IsSmi() ? Smi::cast(map_or_index)->value() : 0; |
3511 i < contents->length(); | 3593 i < contents->length(); |
3512 i += 2) { | 3594 i += 2) { |
3513 PropertyDetails details(Smi::cast(contents->get(i + 1))); | 3595 PropertyDetails details(Smi::cast(contents->get(i + 1))); |
3514 if (details.IsTransition()) { | 3596 if (details.IsTransition()) { |
3515 Map* next = reinterpret_cast<Map*>(contents->get(i)); | 3597 Map* next = reinterpret_cast<Map*>(contents->get(i)); |
3516 next->set_map(current); | 3598 next->set_map(current); |
3517 *map_or_index_field = Smi::FromInt(i + 2); | 3599 *map_or_index_field = Smi::FromInt(i + 2); |
3518 current = next; | 3600 current = next; |
3519 map_done = false; | 3601 map_done = false; |
3520 break; | 3602 break; |
3521 } | 3603 } |
3522 } | 3604 } |
3523 if (!map_done) continue; | 3605 if (!map_done) continue; |
3524 *map_or_index_field = Heap::fixed_array_map(); | 3606 *map_or_index_field = heap()->fixed_array_map(); |
3525 Map* prev = current->map(); | 3607 Map* prev = current->map(); |
3526 current->set_map(Heap::meta_map()); | 3608 current->set_map(meta_map); |
3527 callback(current, data); | 3609 callback(current, data); |
3528 current = prev; | 3610 current = prev; |
3529 } | 3611 } |
3530 } | 3612 } |
3531 | 3613 |
3532 | 3614 |
3533 MaybeObject* CodeCache::Update(String* name, Code* code) { | 3615 MaybeObject* CodeCache::Update(String* name, Code* code) { |
3534 ASSERT(code->ic_state() == MONOMORPHIC); | 3616 ASSERT(code->ic_state() == MONOMORPHIC); |
3535 | 3617 |
3536 // The number of monomorphic stubs for normal load/store/call IC's can grow to | 3618 // The number of monomorphic stubs for normal load/store/call IC's can grow to |
(...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3629 Object* CodeCache::Lookup(String* name, Code::Flags flags) { | 3711 Object* CodeCache::Lookup(String* name, Code::Flags flags) { |
3630 if (Code::ExtractTypeFromFlags(flags) == NORMAL) { | 3712 if (Code::ExtractTypeFromFlags(flags) == NORMAL) { |
3631 return LookupNormalTypeCache(name, flags); | 3713 return LookupNormalTypeCache(name, flags); |
3632 } else { | 3714 } else { |
3633 return LookupDefaultCache(name, flags); | 3715 return LookupDefaultCache(name, flags); |
3634 } | 3716 } |
3635 } | 3717 } |
3636 | 3718 |
3637 | 3719 |
3638 Object* CodeCache::LookupDefaultCache(String* name, Code::Flags flags) { | 3720 Object* CodeCache::LookupDefaultCache(String* name, Code::Flags flags) { |
| 3721 Heap* heap = GetHeap(); |
3639 FixedArray* cache = default_cache(); | 3722 FixedArray* cache = default_cache(); |
3640 int length = cache->length(); | 3723 int length = cache->length(); |
3641 for (int i = 0; i < length; i += kCodeCacheEntrySize) { | 3724 for (int i = 0; i < length; i += kCodeCacheEntrySize) { |
3642 Object* key = cache->get(i + kCodeCacheEntryNameOffset); | 3725 Object* key = cache->get(i + kCodeCacheEntryNameOffset); |
3643 // Skip deleted elements. | 3726 // Skip deleted elements. |
3644 if (key->IsNull()) continue; | 3727 if (key->IsNull()) continue; |
3645 if (key->IsUndefined()) return key; | 3728 if (key->IsUndefined()) return key; |
3646 if (name->Equals(String::cast(key))) { | 3729 if (name->Equals(String::cast(key))) { |
3647 Code* code = Code::cast(cache->get(i + kCodeCacheEntryCodeOffset)); | 3730 Code* code = Code::cast(cache->get(i + kCodeCacheEntryCodeOffset)); |
3648 if (code->flags() == flags) { | 3731 if (code->flags() == flags) { |
3649 return code; | 3732 return code; |
3650 } | 3733 } |
3651 } | 3734 } |
3652 } | 3735 } |
3653 return Heap::undefined_value(); | 3736 return heap->undefined_value(); |
3654 } | 3737 } |
3655 | 3738 |
3656 | 3739 |
3657 Object* CodeCache::LookupNormalTypeCache(String* name, Code::Flags flags) { | 3740 Object* CodeCache::LookupNormalTypeCache(String* name, Code::Flags flags) { |
3658 if (!normal_type_cache()->IsUndefined()) { | 3741 if (!normal_type_cache()->IsUndefined()) { |
3659 CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache()); | 3742 CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache()); |
3660 return cache->Lookup(name, flags); | 3743 return cache->Lookup(name, flags); |
3661 } else { | 3744 } else { |
3662 return Heap::undefined_value(); | 3745 return GetHeap()->undefined_value(); |
3663 } | 3746 } |
3664 } | 3747 } |
3665 | 3748 |
3666 | 3749 |
3667 int CodeCache::GetIndex(Object* name, Code* code) { | 3750 int CodeCache::GetIndex(Object* name, Code* code) { |
3668 if (code->type() == NORMAL) { | 3751 if (code->type() == NORMAL) { |
3669 if (normal_type_cache()->IsUndefined()) return -1; | 3752 if (normal_type_cache()->IsUndefined()) return -1; |
3670 CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache()); | 3753 CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache()); |
3671 return cache->GetIndex(String::cast(name), code->flags()); | 3754 return cache->GetIndex(String::cast(name), code->flags()); |
3672 } | 3755 } |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3734 uint32_t HashForObject(Object* obj) { | 3817 uint32_t HashForObject(Object* obj) { |
3735 FixedArray* pair = FixedArray::cast(obj); | 3818 FixedArray* pair = FixedArray::cast(obj); |
3736 String* name = String::cast(pair->get(0)); | 3819 String* name = String::cast(pair->get(0)); |
3737 Code* code = Code::cast(pair->get(1)); | 3820 Code* code = Code::cast(pair->get(1)); |
3738 return NameFlagsHashHelper(name, code->flags()); | 3821 return NameFlagsHashHelper(name, code->flags()); |
3739 } | 3822 } |
3740 | 3823 |
3741 MUST_USE_RESULT MaybeObject* AsObject() { | 3824 MUST_USE_RESULT MaybeObject* AsObject() { |
3742 ASSERT(code_ != NULL); | 3825 ASSERT(code_ != NULL); |
3743 Object* obj; | 3826 Object* obj; |
3744 { MaybeObject* maybe_obj = Heap::AllocateFixedArray(2); | 3827 { MaybeObject* maybe_obj = code_->GetHeap()->AllocateFixedArray(2); |
3745 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 3828 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
3746 } | 3829 } |
3747 FixedArray* pair = FixedArray::cast(obj); | 3830 FixedArray* pair = FixedArray::cast(obj); |
3748 pair->set(0, name_); | 3831 pair->set(0, name_); |
3749 pair->set(1, code_); | 3832 pair->set(1, code_); |
3750 return pair; | 3833 return pair; |
3751 } | 3834 } |
3752 | 3835 |
3753 private: | 3836 private: |
3754 String* name_; | 3837 String* name_; |
3755 Code::Flags flags_; | 3838 Code::Flags flags_; |
3756 Code* code_; | 3839 Code* code_; |
3757 }; | 3840 }; |
3758 | 3841 |
3759 | 3842 |
3760 Object* CodeCacheHashTable::Lookup(String* name, Code::Flags flags) { | 3843 Object* CodeCacheHashTable::Lookup(String* name, Code::Flags flags) { |
3761 CodeCacheHashTableKey key(name, flags); | 3844 CodeCacheHashTableKey key(name, flags); |
3762 int entry = FindEntry(&key); | 3845 int entry = FindEntry(&key); |
3763 if (entry == kNotFound) return Heap::undefined_value(); | 3846 if (entry == kNotFound) return GetHeap()->undefined_value(); |
3764 return get(EntryToIndex(entry) + 1); | 3847 return get(EntryToIndex(entry) + 1); |
3765 } | 3848 } |
3766 | 3849 |
3767 | 3850 |
3768 MaybeObject* CodeCacheHashTable::Put(String* name, Code* code) { | 3851 MaybeObject* CodeCacheHashTable::Put(String* name, Code* code) { |
3769 CodeCacheHashTableKey key(name, code); | 3852 CodeCacheHashTableKey key(name, code); |
3770 Object* obj; | 3853 Object* obj; |
3771 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); | 3854 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); |
3772 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 3855 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
3773 } | 3856 } |
(...skipping 16 matching lines...) Expand all Loading... |
3790 | 3873 |
3791 int CodeCacheHashTable::GetIndex(String* name, Code::Flags flags) { | 3874 int CodeCacheHashTable::GetIndex(String* name, Code::Flags flags) { |
3792 CodeCacheHashTableKey key(name, flags); | 3875 CodeCacheHashTableKey key(name, flags); |
3793 int entry = FindEntry(&key); | 3876 int entry = FindEntry(&key); |
3794 return (entry == kNotFound) ? -1 : entry; | 3877 return (entry == kNotFound) ? -1 : entry; |
3795 } | 3878 } |
3796 | 3879 |
3797 | 3880 |
3798 void CodeCacheHashTable::RemoveByIndex(int index) { | 3881 void CodeCacheHashTable::RemoveByIndex(int index) { |
3799 ASSERT(index >= 0); | 3882 ASSERT(index >= 0); |
3800 set(EntryToIndex(index), Heap::null_value()); | 3883 Heap* heap = GetHeap(); |
3801 set(EntryToIndex(index) + 1, Heap::null_value()); | 3884 set(EntryToIndex(index), heap->null_value()); |
| 3885 set(EntryToIndex(index) + 1, heap->null_value()); |
3802 ElementRemoved(); | 3886 ElementRemoved(); |
3803 } | 3887 } |
3804 | 3888 |
3805 | 3889 |
3806 static bool HasKey(FixedArray* array, Object* key) { | 3890 static bool HasKey(FixedArray* array, Object* key) { |
3807 int len0 = array->length(); | 3891 int len0 = array->length(); |
3808 for (int i = 0; i < len0; i++) { | 3892 for (int i = 0; i < len0; i++) { |
3809 Object* element = array->get(i); | 3893 Object* element = array->get(i); |
3810 if (element->IsSmi() && key->IsSmi() && (element == key)) return true; | 3894 if (element->IsSmi() && key->IsSmi() && (element == key)) return true; |
3811 if (element->IsString() && | 3895 if (element->IsString() && |
3812 key->IsString() && String::cast(element)->Equals(String::cast(key))) { | 3896 key->IsString() && String::cast(element)->Equals(String::cast(key))) { |
3813 return true; | 3897 return true; |
3814 } | 3898 } |
3815 } | 3899 } |
3816 return false; | 3900 return false; |
3817 } | 3901 } |
3818 | 3902 |
3819 | 3903 |
3820 MaybeObject* FixedArray::AddKeysFromJSArray(JSArray* array) { | 3904 MaybeObject* FixedArray::AddKeysFromJSArray(JSArray* array) { |
| 3905 Heap* heap = GetHeap(); |
3821 ASSERT(!array->HasExternalArrayElements()); | 3906 ASSERT(!array->HasExternalArrayElements()); |
3822 switch (array->GetElementsKind()) { | 3907 switch (array->GetElementsKind()) { |
3823 case JSObject::FAST_ELEMENTS: | 3908 case JSObject::FAST_ELEMENTS: |
3824 return UnionOfKeys(FixedArray::cast(array->elements())); | 3909 return UnionOfKeys(FixedArray::cast(array->elements())); |
3825 case JSObject::DICTIONARY_ELEMENTS: { | 3910 case JSObject::DICTIONARY_ELEMENTS: { |
3826 NumberDictionary* dict = array->element_dictionary(); | 3911 NumberDictionary* dict = array->element_dictionary(); |
3827 int size = dict->NumberOfElements(); | 3912 int size = dict->NumberOfElements(); |
3828 | 3913 |
3829 // Allocate a temporary fixed array. | 3914 // Allocate a temporary fixed array. |
3830 Object* object; | 3915 Object* object; |
3831 { MaybeObject* maybe_object = Heap::AllocateFixedArray(size); | 3916 { MaybeObject* maybe_object = heap->AllocateFixedArray(size); |
3832 if (!maybe_object->ToObject(&object)) return maybe_object; | 3917 if (!maybe_object->ToObject(&object)) return maybe_object; |
3833 } | 3918 } |
3834 FixedArray* key_array = FixedArray::cast(object); | 3919 FixedArray* key_array = FixedArray::cast(object); |
3835 | 3920 |
3836 int capacity = dict->Capacity(); | 3921 int capacity = dict->Capacity(); |
3837 int pos = 0; | 3922 int pos = 0; |
3838 // Copy the elements from the JSArray to the temporary fixed array. | 3923 // Copy the elements from the JSArray to the temporary fixed array. |
3839 for (int i = 0; i < capacity; i++) { | 3924 for (int i = 0; i < capacity; i++) { |
3840 if (dict->IsKey(dict->KeyAt(i))) { | 3925 if (dict->IsKey(dict->KeyAt(i))) { |
3841 key_array->set(pos++, dict->ValueAt(i)); | 3926 key_array->set(pos++, dict->ValueAt(i)); |
3842 } | 3927 } |
3843 } | 3928 } |
3844 // Compute the union of this and the temporary fixed array. | 3929 // Compute the union of this and the temporary fixed array. |
3845 return UnionOfKeys(key_array); | 3930 return UnionOfKeys(key_array); |
3846 } | 3931 } |
3847 default: | 3932 default: |
3848 UNREACHABLE(); | 3933 UNREACHABLE(); |
3849 } | 3934 } |
3850 UNREACHABLE(); | 3935 UNREACHABLE(); |
3851 return Heap::null_value(); // Failure case needs to "return" a value. | 3936 return heap->null_value(); // Failure case needs to "return" a value. |
3852 } | 3937 } |
3853 | 3938 |
3854 | 3939 |
3855 MaybeObject* FixedArray::UnionOfKeys(FixedArray* other) { | 3940 MaybeObject* FixedArray::UnionOfKeys(FixedArray* other) { |
| 3941 Heap* heap = GetHeap(); |
3856 int len0 = length(); | 3942 int len0 = length(); |
3857 #ifdef DEBUG | 3943 #ifdef DEBUG |
3858 if (FLAG_enable_slow_asserts) { | 3944 if (FLAG_enable_slow_asserts) { |
3859 for (int i = 0; i < len0; i++) { | 3945 for (int i = 0; i < len0; i++) { |
3860 ASSERT(get(i)->IsString() || get(i)->IsNumber()); | 3946 ASSERT(get(i)->IsString() || get(i)->IsNumber()); |
3861 } | 3947 } |
3862 } | 3948 } |
3863 #endif | 3949 #endif |
3864 int len1 = other->length(); | 3950 int len1 = other->length(); |
3865 // Optimize if 'other' is empty. | 3951 // Optimize if 'other' is empty. |
3866 // We cannot optimize if 'this' is empty, as other may have holes | 3952 // We cannot optimize if 'this' is empty, as other may have holes |
3867 // or non keys. | 3953 // or non keys. |
3868 if (len1 == 0) return this; | 3954 if (len1 == 0) return this; |
3869 | 3955 |
3870 // Compute how many elements are not in this. | 3956 // Compute how many elements are not in this. |
3871 int extra = 0; | 3957 int extra = 0; |
3872 for (int y = 0; y < len1; y++) { | 3958 for (int y = 0; y < len1; y++) { |
3873 Object* value = other->get(y); | 3959 Object* value = other->get(y); |
3874 if (!value->IsTheHole() && !HasKey(this, value)) extra++; | 3960 if (!value->IsTheHole() && !HasKey(this, value)) extra++; |
3875 } | 3961 } |
3876 | 3962 |
3877 if (extra == 0) return this; | 3963 if (extra == 0) return this; |
3878 | 3964 |
3879 // Allocate the result | 3965 // Allocate the result |
3880 Object* obj; | 3966 Object* obj; |
3881 { MaybeObject* maybe_obj = Heap::AllocateFixedArray(len0 + extra); | 3967 { MaybeObject* maybe_obj = heap->AllocateFixedArray(len0 + extra); |
3882 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 3968 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
3883 } | 3969 } |
3884 // Fill in the content | 3970 // Fill in the content |
3885 AssertNoAllocation no_gc; | 3971 AssertNoAllocation no_gc; |
3886 FixedArray* result = FixedArray::cast(obj); | 3972 FixedArray* result = FixedArray::cast(obj); |
3887 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); | 3973 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); |
3888 for (int i = 0; i < len0; i++) { | 3974 for (int i = 0; i < len0; i++) { |
3889 Object* e = get(i); | 3975 Object* e = get(i); |
3890 ASSERT(e->IsString() || e->IsNumber()); | 3976 ASSERT(e->IsString() || e->IsNumber()); |
3891 result->set(i, e, mode); | 3977 result->set(i, e, mode); |
3892 } | 3978 } |
3893 // Fill in the extra keys. | 3979 // Fill in the extra keys. |
3894 int index = 0; | 3980 int index = 0; |
3895 for (int y = 0; y < len1; y++) { | 3981 for (int y = 0; y < len1; y++) { |
3896 Object* value = other->get(y); | 3982 Object* value = other->get(y); |
3897 if (!value->IsTheHole() && !HasKey(this, value)) { | 3983 if (!value->IsTheHole() && !HasKey(this, value)) { |
3898 Object* e = other->get(y); | 3984 Object* e = other->get(y); |
3899 ASSERT(e->IsString() || e->IsNumber()); | 3985 ASSERT(e->IsString() || e->IsNumber()); |
3900 result->set(len0 + index, e, mode); | 3986 result->set(len0 + index, e, mode); |
3901 index++; | 3987 index++; |
3902 } | 3988 } |
3903 } | 3989 } |
3904 ASSERT(extra == index); | 3990 ASSERT(extra == index); |
3905 return result; | 3991 return result; |
3906 } | 3992 } |
3907 | 3993 |
3908 | 3994 |
3909 MaybeObject* FixedArray::CopySize(int new_length) { | 3995 MaybeObject* FixedArray::CopySize(int new_length) { |
3910 if (new_length == 0) return Heap::empty_fixed_array(); | 3996 Heap* heap = GetHeap(); |
| 3997 if (new_length == 0) return heap->empty_fixed_array(); |
3911 Object* obj; | 3998 Object* obj; |
3912 { MaybeObject* maybe_obj = Heap::AllocateFixedArray(new_length); | 3999 { MaybeObject* maybe_obj = heap->AllocateFixedArray(new_length); |
3913 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 4000 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
3914 } | 4001 } |
3915 FixedArray* result = FixedArray::cast(obj); | 4002 FixedArray* result = FixedArray::cast(obj); |
3916 // Copy the content | 4003 // Copy the content |
3917 AssertNoAllocation no_gc; | 4004 AssertNoAllocation no_gc; |
3918 int len = length(); | 4005 int len = length(); |
3919 if (new_length < len) len = new_length; | 4006 if (new_length < len) len = new_length; |
3920 result->set_map(map()); | 4007 result->set_map(map()); |
3921 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); | 4008 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); |
3922 for (int i = 0; i < len; i++) { | 4009 for (int i = 0; i < len; i++) { |
(...skipping 17 matching lines...) Expand all Loading... |
3940 if (length() != other->length()) return false; | 4027 if (length() != other->length()) return false; |
3941 for (int i = 0 ; i < length(); ++i) { | 4028 for (int i = 0 ; i < length(); ++i) { |
3942 if (get(i) != other->get(i)) return false; | 4029 if (get(i) != other->get(i)) return false; |
3943 } | 4030 } |
3944 return true; | 4031 return true; |
3945 } | 4032 } |
3946 #endif | 4033 #endif |
3947 | 4034 |
3948 | 4035 |
3949 MaybeObject* DescriptorArray::Allocate(int number_of_descriptors) { | 4036 MaybeObject* DescriptorArray::Allocate(int number_of_descriptors) { |
| 4037 Heap* heap = Isolate::Current()->heap(); |
3950 if (number_of_descriptors == 0) { | 4038 if (number_of_descriptors == 0) { |
3951 return Heap::empty_descriptor_array(); | 4039 return heap->empty_descriptor_array(); |
3952 } | 4040 } |
3953 // Allocate the array of keys. | 4041 // Allocate the array of keys. |
3954 Object* array; | 4042 Object* array; |
3955 { MaybeObject* maybe_array = | 4043 { MaybeObject* maybe_array = |
3956 Heap::AllocateFixedArray(ToKeyIndex(number_of_descriptors)); | 4044 heap->AllocateFixedArray(ToKeyIndex(number_of_descriptors)); |
3957 if (!maybe_array->ToObject(&array)) return maybe_array; | 4045 if (!maybe_array->ToObject(&array)) return maybe_array; |
3958 } | 4046 } |
3959 // Do not use DescriptorArray::cast on incomplete object. | 4047 // Do not use DescriptorArray::cast on incomplete object. |
3960 FixedArray* result = FixedArray::cast(array); | 4048 FixedArray* result = FixedArray::cast(array); |
3961 | 4049 |
3962 // Allocate the content array and set it in the descriptor array. | 4050 // Allocate the content array and set it in the descriptor array. |
3963 { MaybeObject* maybe_array = | 4051 { MaybeObject* maybe_array = |
3964 Heap::AllocateFixedArray(number_of_descriptors << 1); | 4052 heap->AllocateFixedArray(number_of_descriptors << 1); |
3965 if (!maybe_array->ToObject(&array)) return maybe_array; | 4053 if (!maybe_array->ToObject(&array)) return maybe_array; |
3966 } | 4054 } |
3967 result->set(kContentArrayIndex, array); | 4055 result->set(kContentArrayIndex, array); |
3968 result->set(kEnumerationIndexIndex, | 4056 result->set(kEnumerationIndexIndex, |
3969 Smi::FromInt(PropertyDetails::kInitialIndex)); | 4057 Smi::FromInt(PropertyDetails::kInitialIndex)); |
3970 return result; | 4058 return result; |
3971 } | 4059 } |
3972 | 4060 |
3973 | 4061 |
3974 void DescriptorArray::SetEnumCache(FixedArray* bridge_storage, | 4062 void DescriptorArray::SetEnumCache(FixedArray* bridge_storage, |
(...skipping 248 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4223 return number; | 4311 return number; |
4224 } | 4312 } |
4225 } | 4313 } |
4226 return kNotFound; | 4314 return kNotFound; |
4227 } | 4315 } |
4228 | 4316 |
4229 | 4317 |
4230 MaybeObject* DeoptimizationInputData::Allocate(int deopt_entry_count, | 4318 MaybeObject* DeoptimizationInputData::Allocate(int deopt_entry_count, |
4231 PretenureFlag pretenure) { | 4319 PretenureFlag pretenure) { |
4232 ASSERT(deopt_entry_count > 0); | 4320 ASSERT(deopt_entry_count > 0); |
4233 return Heap::AllocateFixedArray(LengthFor(deopt_entry_count), | 4321 return HEAP->AllocateFixedArray(LengthFor(deopt_entry_count), |
4234 pretenure); | 4322 pretenure); |
4235 } | 4323 } |
4236 | 4324 |
4237 | 4325 |
4238 MaybeObject* DeoptimizationOutputData::Allocate(int number_of_deopt_points, | 4326 MaybeObject* DeoptimizationOutputData::Allocate(int number_of_deopt_points, |
4239 PretenureFlag pretenure) { | 4327 PretenureFlag pretenure) { |
4240 if (number_of_deopt_points == 0) return Heap::empty_fixed_array(); | 4328 if (number_of_deopt_points == 0) return HEAP->empty_fixed_array(); |
4241 return Heap::AllocateFixedArray(LengthOfFixedArray(number_of_deopt_points), | 4329 return HEAP->AllocateFixedArray(LengthOfFixedArray(number_of_deopt_points), |
4242 pretenure); | 4330 pretenure); |
4243 } | 4331 } |
4244 | 4332 |
4245 | 4333 |
4246 #ifdef DEBUG | 4334 #ifdef DEBUG |
4247 bool DescriptorArray::IsEqualTo(DescriptorArray* other) { | 4335 bool DescriptorArray::IsEqualTo(DescriptorArray* other) { |
4248 if (IsEmpty()) return other->IsEmpty(); | 4336 if (IsEmpty()) return other->IsEmpty(); |
4249 if (other->IsEmpty()) return false; | 4337 if (other->IsEmpty()) return false; |
4250 if (length() != other->length()) return false; | 4338 if (length() != other->length()) return false; |
4251 for (int i = 0; i < length(); ++i) { | 4339 for (int i = 0; i < length(); ++i) { |
4252 if (get(i) != other->get(i) && i != kContentArrayIndex) return false; | 4340 if (get(i) != other->get(i) && i != kContentArrayIndex) return false; |
4253 } | 4341 } |
4254 return GetContentArray()->IsEqualTo(other->GetContentArray()); | 4342 return GetContentArray()->IsEqualTo(other->GetContentArray()); |
4255 } | 4343 } |
4256 #endif | 4344 #endif |
4257 | 4345 |
4258 | 4346 |
4259 static StaticResource<StringInputBuffer> string_input_buffer; | |
4260 | |
4261 | |
4262 bool String::LooksValid() { | 4347 bool String::LooksValid() { |
4263 if (!Heap::Contains(this)) return false; | 4348 if (!Isolate::Current()->heap()->Contains(this)) return false; |
4264 return true; | 4349 return true; |
4265 } | 4350 } |
4266 | 4351 |
4267 | 4352 |
4268 int String::Utf8Length() { | 4353 int String::Utf8Length() { |
4269 if (IsAsciiRepresentation()) return length(); | 4354 if (IsAsciiRepresentation()) return length(); |
4270 // Attempt to flatten before accessing the string. It probably | 4355 // Attempt to flatten before accessing the string. It probably |
4271 // doesn't make Utf8Length faster, but it is very likely that | 4356 // doesn't make Utf8Length faster, but it is very likely that |
4272 // the string will be accessed later (for example by WriteUtf8) | 4357 // the string will be accessed later (for example by WriteUtf8) |
4273 // so it's still a good idea. | 4358 // so it's still a good idea. |
| 4359 Heap* heap = GetHeap(); |
4274 TryFlatten(); | 4360 TryFlatten(); |
4275 Access<StringInputBuffer> buffer(&string_input_buffer); | 4361 Access<StringInputBuffer> buffer( |
| 4362 heap->isolate()->objects_string_input_buffer()); |
4276 buffer->Reset(0, this); | 4363 buffer->Reset(0, this); |
4277 int result = 0; | 4364 int result = 0; |
4278 while (buffer->has_more()) | 4365 while (buffer->has_more()) |
4279 result += unibrow::Utf8::Length(buffer->GetNext()); | 4366 result += unibrow::Utf8::Length(buffer->GetNext()); |
4280 return result; | 4367 return result; |
4281 } | 4368 } |
4282 | 4369 |
4283 | 4370 |
4284 Vector<const char> String::ToAsciiVector() { | 4371 Vector<const char> String::ToAsciiVector() { |
4285 ASSERT(IsAsciiRepresentation()); | 4372 ASSERT(IsAsciiRepresentation()); |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4335 | 4422 |
4336 SmartPointer<char> String::ToCString(AllowNullsFlag allow_nulls, | 4423 SmartPointer<char> String::ToCString(AllowNullsFlag allow_nulls, |
4337 RobustnessFlag robust_flag, | 4424 RobustnessFlag robust_flag, |
4338 int offset, | 4425 int offset, |
4339 int length, | 4426 int length, |
4340 int* length_return) { | 4427 int* length_return) { |
4341 ASSERT(NativeAllocationChecker::allocation_allowed()); | 4428 ASSERT(NativeAllocationChecker::allocation_allowed()); |
4342 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) { | 4429 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) { |
4343 return SmartPointer<char>(NULL); | 4430 return SmartPointer<char>(NULL); |
4344 } | 4431 } |
| 4432 Heap* heap = GetHeap(); |
4345 | 4433 |
4346 // Negative length means the to the end of the string. | 4434 // Negative length means the to the end of the string. |
4347 if (length < 0) length = kMaxInt - offset; | 4435 if (length < 0) length = kMaxInt - offset; |
4348 | 4436 |
4349 // Compute the size of the UTF-8 string. Start at the specified offset. | 4437 // Compute the size of the UTF-8 string. Start at the specified offset. |
4350 Access<StringInputBuffer> buffer(&string_input_buffer); | 4438 Access<StringInputBuffer> buffer( |
| 4439 heap->isolate()->objects_string_input_buffer()); |
4351 buffer->Reset(offset, this); | 4440 buffer->Reset(offset, this); |
4352 int character_position = offset; | 4441 int character_position = offset; |
4353 int utf8_bytes = 0; | 4442 int utf8_bytes = 0; |
4354 while (buffer->has_more()) { | 4443 while (buffer->has_more()) { |
4355 uint16_t character = buffer->GetNext(); | 4444 uint16_t character = buffer->GetNext(); |
4356 if (character_position < offset + length) { | 4445 if (character_position < offset + length) { |
4357 utf8_bytes += unibrow::Utf8::Length(character); | 4446 utf8_bytes += unibrow::Utf8::Length(character); |
4358 } | 4447 } |
4359 character_position++; | 4448 character_position++; |
4360 } | 4449 } |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4410 UNREACHABLE(); | 4499 UNREACHABLE(); |
4411 return NULL; | 4500 return NULL; |
4412 } | 4501 } |
4413 UNREACHABLE(); | 4502 UNREACHABLE(); |
4414 return NULL; | 4503 return NULL; |
4415 } | 4504 } |
4416 | 4505 |
4417 | 4506 |
4418 SmartPointer<uc16> String::ToWideCString(RobustnessFlag robust_flag) { | 4507 SmartPointer<uc16> String::ToWideCString(RobustnessFlag robust_flag) { |
4419 ASSERT(NativeAllocationChecker::allocation_allowed()); | 4508 ASSERT(NativeAllocationChecker::allocation_allowed()); |
4420 | |
4421 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) { | 4509 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) { |
4422 return SmartPointer<uc16>(); | 4510 return SmartPointer<uc16>(); |
4423 } | 4511 } |
| 4512 Heap* heap = GetHeap(); |
4424 | 4513 |
4425 Access<StringInputBuffer> buffer(&string_input_buffer); | 4514 Access<StringInputBuffer> buffer( |
| 4515 heap->isolate()->objects_string_input_buffer()); |
4426 buffer->Reset(this); | 4516 buffer->Reset(this); |
4427 | 4517 |
4428 uc16* result = NewArray<uc16>(length() + 1); | 4518 uc16* result = NewArray<uc16>(length() + 1); |
4429 | 4519 |
4430 int i = 0; | 4520 int i = 0; |
4431 while (buffer->has_more()) { | 4521 while (buffer->has_more()) { |
4432 uint16_t character = buffer->GetNext(); | 4522 uint16_t character = buffer->GetNext(); |
4433 result[i++] = character; | 4523 result[i++] = character; |
4434 } | 4524 } |
4435 result[i] = 0; | 4525 result[i] = 0; |
(...skipping 262 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
4698 } | 4788 } |
4699 default: | 4789 default: |
4700 break; | 4790 break; |
4701 } | 4791 } |
4702 | 4792 |
4703 UNREACHABLE(); | 4793 UNREACHABLE(); |
4704 return 0; | 4794 return 0; |
4705 } | 4795 } |
4706 | 4796 |
4707 | 4797 |
4708 Relocatable* Relocatable::top_ = NULL; | |
4709 | |
4710 | |
4711 void Relocatable::PostGarbageCollectionProcessing() { | 4798 void Relocatable::PostGarbageCollectionProcessing() { |
4712 Relocatable* current = top_; | 4799 Isolate* isolate = Isolate::Current(); |
| 4800 Relocatable* current = isolate->relocatable_top(); |
4713 while (current != NULL) { | 4801 while (current != NULL) { |
4714 current->PostGarbageCollection(); | 4802 current->PostGarbageCollection(); |
4715 current = current->prev_; | 4803 current = current->prev_; |
4716 } | 4804 } |
4717 } | 4805 } |
4718 | 4806 |
4719 | 4807 |
4720 // Reserve space for statics needing saving and restoring. | 4808 // Reserve space for statics needing saving and restoring. |
4721 int Relocatable::ArchiveSpacePerThread() { | 4809 int Relocatable::ArchiveSpacePerThread() { |
4722 return sizeof(top_); | 4810 return sizeof(Isolate::Current()->relocatable_top()); |
4723 } | 4811 } |
4724 | 4812 |
4725 | 4813 |
4726 // Archive statics that are thread local. | 4814 // Archive statics that are thread local. |
4727 char* Relocatable::ArchiveState(char* to) { | 4815 char* Relocatable::ArchiveState(char* to) { |
4728 *reinterpret_cast<Relocatable**>(to) = top_; | 4816 Isolate* isolate = Isolate::Current(); |
4729 top_ = NULL; | 4817 *reinterpret_cast<Relocatable**>(to) = isolate->relocatable_top(); |
| 4818 isolate->set_relocatable_top(NULL); |
4730 return to + ArchiveSpacePerThread(); | 4819 return to + ArchiveSpacePerThread(); |
4731 } | 4820 } |
4732 | 4821 |
4733 | 4822 |
4734 // Restore statics that are thread local. | 4823 // Restore statics that are thread local. |
4735 char* Relocatable::RestoreState(char* from) { | 4824 char* Relocatable::RestoreState(char* from) { |
4736 top_ = *reinterpret_cast<Relocatable**>(from); | 4825 Isolate* isolate = Isolate::Current(); |
| 4826 isolate->set_relocatable_top(*reinterpret_cast<Relocatable**>(from)); |
4737 return from + ArchiveSpacePerThread(); | 4827 return from + ArchiveSpacePerThread(); |
4738 } | 4828 } |
4739 | 4829 |
4740 | 4830 |
4741 char* Relocatable::Iterate(ObjectVisitor* v, char* thread_storage) { | 4831 char* Relocatable::Iterate(ObjectVisitor* v, char* thread_storage) { |
4742 Relocatable* top = *reinterpret_cast<Relocatable**>(thread_storage); | 4832 Relocatable* top = *reinterpret_cast<Relocatable**>(thread_storage); |
4743 Iterate(v, top); | 4833 Iterate(v, top); |
4744 return thread_storage + ArchiveSpacePerThread(); | 4834 return thread_storage + ArchiveSpacePerThread(); |
4745 } | 4835 } |
4746 | 4836 |
4747 | 4837 |
4748 void Relocatable::Iterate(ObjectVisitor* v) { | 4838 void Relocatable::Iterate(ObjectVisitor* v) { |
4749 Iterate(v, top_); | 4839 Isolate* isolate = Isolate::Current(); |
| 4840 Iterate(v, isolate->relocatable_top()); |
4750 } | 4841 } |
4751 | 4842 |
4752 | 4843 |
4753 void Relocatable::Iterate(ObjectVisitor* v, Relocatable* top) { | 4844 void Relocatable::Iterate(ObjectVisitor* v, Relocatable* top) { |
4754 Relocatable* current = top; | 4845 Relocatable* current = top; |
4755 while (current != NULL) { | 4846 while (current != NULL) { |
4756 current->IterateInstance(v); | 4847 current->IterateInstance(v); |
4757 current = current->prev_; | 4848 current = current->prev_; |
4758 } | 4849 } |
4759 } | 4850 } |
4760 | 4851 |
4761 | 4852 |
4762 FlatStringReader::FlatStringReader(Handle<String> str) | 4853 FlatStringReader::FlatStringReader(Isolate* isolate, Handle<String> str) |
4763 : str_(str.location()), | 4854 : Relocatable(isolate), |
| 4855 str_(str.location()), |
4764 length_(str->length()) { | 4856 length_(str->length()) { |
4765 PostGarbageCollection(); | 4857 PostGarbageCollection(); |
4766 } | 4858 } |
4767 | 4859 |
4768 | 4860 |
4769 FlatStringReader::FlatStringReader(Vector<const char> input) | 4861 FlatStringReader::FlatStringReader(Isolate* isolate, Vector<const char> input) |
4770 : str_(0), | 4862 : Relocatable(isolate), |
| 4863 str_(0), |
4771 is_ascii_(true), | 4864 is_ascii_(true), |
4772 length_(input.length()), | 4865 length_(input.length()), |
4773 start_(input.start()) { } | 4866 start_(input.start()) { } |
4774 | 4867 |
4775 | 4868 |
4776 void FlatStringReader::PostGarbageCollection() { | 4869 void FlatStringReader::PostGarbageCollection() { |
4777 if (str_ == NULL) return; | 4870 if (str_ == NULL) return; |
4778 Handle<String> str(str_); | 4871 Handle<String> str(str_); |
4779 ASSERT(str->IsFlat()); | 4872 ASSERT(str->IsFlat()); |
4780 is_ascii_ = str->IsAsciiRepresentation(); | 4873 is_ascii_ = str->IsAsciiRepresentation(); |
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5090 // Compare the remaining characters that didn't fit into a block. | 5183 // Compare the remaining characters that didn't fit into a block. |
5091 for (; i < length; i++) { | 5184 for (; i < length; i++) { |
5092 if (a[i] != b[i]) { | 5185 if (a[i] != b[i]) { |
5093 return false; | 5186 return false; |
5094 } | 5187 } |
5095 } | 5188 } |
5096 return true; | 5189 return true; |
5097 } | 5190 } |
5098 | 5191 |
5099 | 5192 |
5100 static StringInputBuffer string_compare_buffer_b; | |
5101 | |
5102 | |
5103 template <typename IteratorA> | 5193 template <typename IteratorA> |
5104 static inline bool CompareStringContentsPartial(IteratorA* ia, String* b) { | 5194 static inline bool CompareStringContentsPartial(Isolate* isolate, |
| 5195 IteratorA* ia, |
| 5196 String* b) { |
5105 if (b->IsFlat()) { | 5197 if (b->IsFlat()) { |
5106 if (b->IsAsciiRepresentation()) { | 5198 if (b->IsAsciiRepresentation()) { |
5107 VectorIterator<char> ib(b->ToAsciiVector()); | 5199 VectorIterator<char> ib(b->ToAsciiVector()); |
5108 return CompareStringContents(ia, &ib); | 5200 return CompareStringContents(ia, &ib); |
5109 } else { | 5201 } else { |
5110 VectorIterator<uc16> ib(b->ToUC16Vector()); | 5202 VectorIterator<uc16> ib(b->ToUC16Vector()); |
5111 return CompareStringContents(ia, &ib); | 5203 return CompareStringContents(ia, &ib); |
5112 } | 5204 } |
5113 } else { | 5205 } else { |
5114 string_compare_buffer_b.Reset(0, b); | 5206 isolate->objects_string_compare_buffer_b()->Reset(0, b); |
5115 return CompareStringContents(ia, &string_compare_buffer_b); | 5207 return CompareStringContents(ia, |
| 5208 isolate->objects_string_compare_buffer_b()); |
5116 } | 5209 } |
5117 } | 5210 } |
5118 | 5211 |
5119 | 5212 |
5120 static StringInputBuffer string_compare_buffer_a; | 5213 bool String::SlowEquals(String* other) { |
| 5214 Heap* heap = GetHeap(); |
5121 | 5215 |
5122 | |
5123 bool String::SlowEquals(String* other) { | |
5124 // Fast check: negative check with lengths. | 5216 // Fast check: negative check with lengths. |
5125 int len = length(); | 5217 int len = length(); |
5126 if (len != other->length()) return false; | 5218 if (len != other->length()) return false; |
5127 if (len == 0) return true; | 5219 if (len == 0) return true; |
5128 | 5220 |
5129 // Fast check: if hash code is computed for both strings | 5221 // Fast check: if hash code is computed for both strings |
5130 // a fast negative check can be performed. | 5222 // a fast negative check can be performed. |
5131 if (HasHashCode() && other->HasHashCode()) { | 5223 if (HasHashCode() && other->HasHashCode()) { |
5132 if (Hash() != other->Hash()) return false; | 5224 if (Hash() != other->Hash()) return false; |
5133 } | 5225 } |
5134 | 5226 |
5135 // We know the strings are both non-empty. Compare the first chars | 5227 // We know the strings are both non-empty. Compare the first chars |
5136 // before we try to flatten the strings. | 5228 // before we try to flatten the strings. |
5137 if (this->Get(0) != other->Get(0)) return false; | 5229 if (this->Get(0) != other->Get(0)) return false; |
5138 | 5230 |
5139 String* lhs = this->TryFlattenGetString(); | 5231 String* lhs = this->TryFlattenGetString(); |
5140 String* rhs = other->TryFlattenGetString(); | 5232 String* rhs = other->TryFlattenGetString(); |
5141 | 5233 |
5142 if (StringShape(lhs).IsSequentialAscii() && | 5234 if (StringShape(lhs).IsSequentialAscii() && |
5143 StringShape(rhs).IsSequentialAscii()) { | 5235 StringShape(rhs).IsSequentialAscii()) { |
5144 const char* str1 = SeqAsciiString::cast(lhs)->GetChars(); | 5236 const char* str1 = SeqAsciiString::cast(lhs)->GetChars(); |
5145 const char* str2 = SeqAsciiString::cast(rhs)->GetChars(); | 5237 const char* str2 = SeqAsciiString::cast(rhs)->GetChars(); |
5146 return CompareRawStringContents(Vector<const char>(str1, len), | 5238 return CompareRawStringContents(Vector<const char>(str1, len), |
5147 Vector<const char>(str2, len)); | 5239 Vector<const char>(str2, len)); |
5148 } | 5240 } |
5149 | 5241 |
| 5242 Isolate* isolate = heap->isolate(); |
5150 if (lhs->IsFlat()) { | 5243 if (lhs->IsFlat()) { |
5151 if (lhs->IsAsciiRepresentation()) { | 5244 if (lhs->IsAsciiRepresentation()) { |
5152 Vector<const char> vec1 = lhs->ToAsciiVector(); | 5245 Vector<const char> vec1 = lhs->ToAsciiVector(); |
5153 if (rhs->IsFlat()) { | 5246 if (rhs->IsFlat()) { |
5154 if (rhs->IsAsciiRepresentation()) { | 5247 if (rhs->IsAsciiRepresentation()) { |
5155 Vector<const char> vec2 = rhs->ToAsciiVector(); | 5248 Vector<const char> vec2 = rhs->ToAsciiVector(); |
5156 return CompareRawStringContents(vec1, vec2); | 5249 return CompareRawStringContents(vec1, vec2); |
5157 } else { | 5250 } else { |
5158 VectorIterator<char> buf1(vec1); | 5251 VectorIterator<char> buf1(vec1); |
5159 VectorIterator<uc16> ib(rhs->ToUC16Vector()); | 5252 VectorIterator<uc16> ib(rhs->ToUC16Vector()); |
5160 return CompareStringContents(&buf1, &ib); | 5253 return CompareStringContents(&buf1, &ib); |
5161 } | 5254 } |
5162 } else { | 5255 } else { |
5163 VectorIterator<char> buf1(vec1); | 5256 VectorIterator<char> buf1(vec1); |
5164 string_compare_buffer_b.Reset(0, rhs); | 5257 isolate->objects_string_compare_buffer_b()->Reset(0, rhs); |
5165 return CompareStringContents(&buf1, &string_compare_buffer_b); | 5258 return CompareStringContents(&buf1, |
| 5259 isolate->objects_string_compare_buffer_b()); |
5166 } | 5260 } |
5167 } else { | 5261 } else { |
5168 Vector<const uc16> vec1 = lhs->ToUC16Vector(); | 5262 Vector<const uc16> vec1 = lhs->ToUC16Vector(); |
5169 if (rhs->IsFlat()) { | 5263 if (rhs->IsFlat()) { |
5170 if (rhs->IsAsciiRepresentation()) { | 5264 if (rhs->IsAsciiRepresentation()) { |
5171 VectorIterator<uc16> buf1(vec1); | 5265 VectorIterator<uc16> buf1(vec1); |
5172 VectorIterator<char> ib(rhs->ToAsciiVector()); | 5266 VectorIterator<char> ib(rhs->ToAsciiVector()); |
5173 return CompareStringContents(&buf1, &ib); | 5267 return CompareStringContents(&buf1, &ib); |
5174 } else { | 5268 } else { |
5175 Vector<const uc16> vec2(rhs->ToUC16Vector()); | 5269 Vector<const uc16> vec2(rhs->ToUC16Vector()); |
5176 return CompareRawStringContents(vec1, vec2); | 5270 return CompareRawStringContents(vec1, vec2); |
5177 } | 5271 } |
5178 } else { | 5272 } else { |
5179 VectorIterator<uc16> buf1(vec1); | 5273 VectorIterator<uc16> buf1(vec1); |
5180 string_compare_buffer_b.Reset(0, rhs); | 5274 isolate->objects_string_compare_buffer_b()->Reset(0, rhs); |
5181 return CompareStringContents(&buf1, &string_compare_buffer_b); | 5275 return CompareStringContents(&buf1, |
| 5276 isolate->objects_string_compare_buffer_b()); |
5182 } | 5277 } |
5183 } | 5278 } |
5184 } else { | 5279 } else { |
5185 string_compare_buffer_a.Reset(0, lhs); | 5280 isolate->objects_string_compare_buffer_a()->Reset(0, lhs); |
5186 return CompareStringContentsPartial(&string_compare_buffer_a, rhs); | 5281 return CompareStringContentsPartial(isolate, |
| 5282 isolate->objects_string_compare_buffer_a(), rhs); |
5187 } | 5283 } |
5188 } | 5284 } |
5189 | 5285 |
5190 | 5286 |
5191 bool String::MarkAsUndetectable() { | 5287 bool String::MarkAsUndetectable() { |
5192 if (StringShape(this).IsSymbol()) return false; | 5288 if (StringShape(this).IsSymbol()) return false; |
5193 | 5289 |
5194 Map* map = this->map(); | 5290 Map* map = this->map(); |
5195 if (map == Heap::string_map()) { | 5291 Heap* heap = map->GetHeap(); |
5196 this->set_map(Heap::undetectable_string_map()); | 5292 if (map == heap->string_map()) { |
| 5293 this->set_map(heap->undetectable_string_map()); |
5197 return true; | 5294 return true; |
5198 } else if (map == Heap::ascii_string_map()) { | 5295 } else if (map == heap->ascii_string_map()) { |
5199 this->set_map(Heap::undetectable_ascii_string_map()); | 5296 this->set_map(heap->undetectable_ascii_string_map()); |
5200 return true; | 5297 return true; |
5201 } | 5298 } |
5202 // Rest cannot be marked as undetectable | 5299 // Rest cannot be marked as undetectable |
5203 return false; | 5300 return false; |
5204 } | 5301 } |
5205 | 5302 |
5206 | 5303 |
5207 bool String::IsEqualTo(Vector<const char> str) { | 5304 bool String::IsEqualTo(Vector<const char> str) { |
| 5305 Isolate* isolate = GetIsolate(); |
5208 int slen = length(); | 5306 int slen = length(); |
5209 Access<ScannerConstants::Utf8Decoder> | 5307 Access<ScannerConstants::Utf8Decoder> |
5210 decoder(ScannerConstants::utf8_decoder()); | 5308 decoder(isolate->scanner_constants()->utf8_decoder()); |
5211 decoder->Reset(str.start(), str.length()); | 5309 decoder->Reset(str.start(), str.length()); |
5212 int i; | 5310 int i; |
5213 for (i = 0; i < slen && decoder->has_more(); i++) { | 5311 for (i = 0; i < slen && decoder->has_more(); i++) { |
5214 uc32 r = decoder->GetNext(); | 5312 uc32 r = decoder->GetNext(); |
5215 if (Get(i) != r) return false; | 5313 if (Get(i) != r) return false; |
5216 } | 5314 } |
5217 return i == slen && !decoder->has_more(); | 5315 return i == slen && !decoder->has_more(); |
5218 } | 5316 } |
5219 | 5317 |
5220 | 5318 |
(...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5362 // index. | 5460 // index. |
5363 while (buffer->has_more()) { | 5461 while (buffer->has_more()) { |
5364 hasher.AddCharacterNoIndex(buffer->GetNext()); | 5462 hasher.AddCharacterNoIndex(buffer->GetNext()); |
5365 } | 5463 } |
5366 | 5464 |
5367 return hasher.GetHashField(); | 5465 return hasher.GetHashField(); |
5368 } | 5466 } |
5369 | 5467 |
5370 | 5468 |
5371 MaybeObject* String::SubString(int start, int end, PretenureFlag pretenure) { | 5469 MaybeObject* String::SubString(int start, int end, PretenureFlag pretenure) { |
| 5470 Heap* heap = GetHeap(); |
5372 if (start == 0 && end == length()) return this; | 5471 if (start == 0 && end == length()) return this; |
5373 MaybeObject* result = Heap::AllocateSubString(this, start, end, pretenure); | 5472 MaybeObject* result = heap->AllocateSubString(this, start, end, pretenure); |
5374 return result; | 5473 return result; |
5375 } | 5474 } |
5376 | 5475 |
5377 | 5476 |
5378 void String::PrintOn(FILE* file) { | 5477 void String::PrintOn(FILE* file) { |
5379 int length = this->length(); | 5478 int length = this->length(); |
5380 for (int i = 0; i < length; i++) { | 5479 for (int i = 0; i < length; i++) { |
5381 fprintf(file, "%c", Get(i)); | 5480 fprintf(file, "%c", Get(i)); |
5382 } | 5481 } |
5383 } | 5482 } |
(...skipping 19 matching lines...) Expand all Loading... |
5403 source_prototype == target_prototype); | 5502 source_prototype == target_prototype); |
5404 #endif | 5503 #endif |
5405 // Point target back to source. set_prototype() will not let us set | 5504 // Point target back to source. set_prototype() will not let us set |
5406 // the prototype to a map, as we do here. | 5505 // the prototype to a map, as we do here. |
5407 *RawField(target, kPrototypeOffset) = this; | 5506 *RawField(target, kPrototypeOffset) = this; |
5408 } | 5507 } |
5409 } | 5508 } |
5410 } | 5509 } |
5411 | 5510 |
5412 | 5511 |
5413 void Map::ClearNonLiveTransitions(Object* real_prototype) { | 5512 void Map::ClearNonLiveTransitions(Heap* heap, Object* real_prototype) { |
5414 // Live DescriptorArray objects will be marked, so we must use | 5513 // Live DescriptorArray objects will be marked, so we must use |
5415 // low-level accessors to get and modify their data. | 5514 // low-level accessors to get and modify their data. |
5416 DescriptorArray* d = reinterpret_cast<DescriptorArray*>( | 5515 DescriptorArray* d = reinterpret_cast<DescriptorArray*>( |
5417 *RawField(this, Map::kInstanceDescriptorsOffset)); | 5516 *RawField(this, Map::kInstanceDescriptorsOffset)); |
5418 if (d == Heap::raw_unchecked_empty_descriptor_array()) return; | 5517 if (d == heap->raw_unchecked_empty_descriptor_array()) return; |
5419 Smi* NullDescriptorDetails = | 5518 Smi* NullDescriptorDetails = |
5420 PropertyDetails(NONE, NULL_DESCRIPTOR).AsSmi(); | 5519 PropertyDetails(NONE, NULL_DESCRIPTOR).AsSmi(); |
5421 FixedArray* contents = reinterpret_cast<FixedArray*>( | 5520 FixedArray* contents = reinterpret_cast<FixedArray*>( |
5422 d->get(DescriptorArray::kContentArrayIndex)); | 5521 d->get(DescriptorArray::kContentArrayIndex)); |
5423 ASSERT(contents->length() >= 2); | 5522 ASSERT(contents->length() >= 2); |
5424 for (int i = 0; i < contents->length(); i += 2) { | 5523 for (int i = 0; i < contents->length(); i += 2) { |
5425 // If the pair (value, details) is a map transition, | 5524 // If the pair (value, details) is a map transition, |
5426 // check if the target is live. If not, null the descriptor. | 5525 // check if the target is live. If not, null the descriptor. |
5427 // Also drop the back pointer for that map transition, so that this | 5526 // Also drop the back pointer for that map transition, so that this |
5428 // map is not reached again by following a back pointer from a | 5527 // map is not reached again by following a back pointer from a |
5429 // non-live object. | 5528 // non-live object. |
5430 PropertyDetails details(Smi::cast(contents->get(i + 1))); | 5529 PropertyDetails details(Smi::cast(contents->get(i + 1))); |
5431 if (details.type() == MAP_TRANSITION || | 5530 if (details.type() == MAP_TRANSITION || |
5432 details.type() == CONSTANT_TRANSITION) { | 5531 details.type() == CONSTANT_TRANSITION) { |
5433 Map* target = reinterpret_cast<Map*>(contents->get(i)); | 5532 Map* target = reinterpret_cast<Map*>(contents->get(i)); |
5434 ASSERT(target->IsHeapObject()); | 5533 ASSERT(target->IsHeapObject()); |
5435 if (!target->IsMarked()) { | 5534 if (!target->IsMarked()) { |
5436 ASSERT(target->IsMap()); | 5535 ASSERT(target->IsMap()); |
5437 contents->set_unchecked(i + 1, NullDescriptorDetails); | 5536 contents->set_unchecked(i + 1, NullDescriptorDetails); |
5438 contents->set_null_unchecked(i); | 5537 contents->set_null_unchecked(heap, i); |
5439 ASSERT(target->prototype() == this || | 5538 ASSERT(target->prototype() == this || |
5440 target->prototype() == real_prototype); | 5539 target->prototype() == real_prototype); |
5441 // Getter prototype() is read-only, set_prototype() has side effects. | 5540 // Getter prototype() is read-only, set_prototype() has side effects. |
5442 *RawField(target, Map::kPrototypeOffset) = real_prototype; | 5541 *RawField(target, Map::kPrototypeOffset) = real_prototype; |
5443 } | 5542 } |
5444 } | 5543 } |
5445 } | 5544 } |
5446 } | 5545 } |
5447 | 5546 |
5448 | 5547 |
5449 void JSFunction::JSFunctionIterateBody(int object_size, ObjectVisitor* v) { | 5548 void JSFunction::JSFunctionIterateBody(int object_size, ObjectVisitor* v) { |
5450 // Iterate over all fields in the body but take care in dealing with | 5549 // Iterate over all fields in the body but take care in dealing with |
5451 // the code entry. | 5550 // the code entry. |
5452 IteratePointers(v, kPropertiesOffset, kCodeEntryOffset); | 5551 IteratePointers(v, kPropertiesOffset, kCodeEntryOffset); |
5453 v->VisitCodeEntry(this->address() + kCodeEntryOffset); | 5552 v->VisitCodeEntry(this->address() + kCodeEntryOffset); |
5454 IteratePointers(v, kCodeEntryOffset + kPointerSize, object_size); | 5553 IteratePointers(v, kCodeEntryOffset + kPointerSize, object_size); |
5455 } | 5554 } |
5456 | 5555 |
5457 | 5556 |
5458 void JSFunction::MarkForLazyRecompilation() { | 5557 void JSFunction::MarkForLazyRecompilation() { |
5459 ASSERT(is_compiled() && !IsOptimized()); | 5558 ASSERT(is_compiled() && !IsOptimized()); |
5460 ASSERT(shared()->allows_lazy_compilation() || | 5559 ASSERT(shared()->allows_lazy_compilation() || |
5461 code()->optimizable()); | 5560 code()->optimizable()); |
5462 ReplaceCode(Builtins::builtin(Builtins::LazyRecompile)); | 5561 Builtins* builtins = GetIsolate()->builtins(); |
| 5562 ReplaceCode(builtins->builtin(Builtins::LazyRecompile)); |
5463 } | 5563 } |
5464 | 5564 |
5465 | 5565 |
5466 uint32_t JSFunction::SourceHash() { | 5566 uint32_t JSFunction::SourceHash() { |
5467 uint32_t hash = 0; | 5567 uint32_t hash = 0; |
5468 Object* script = shared()->script(); | 5568 Object* script = shared()->script(); |
5469 if (!script->IsUndefined()) { | 5569 if (!script->IsUndefined()) { |
5470 Object* source = Script::cast(script)->source(); | 5570 Object* source = Script::cast(script)->source(); |
5471 if (source->IsUndefined()) hash = String::cast(source)->Hash(); | 5571 if (source->IsUndefined()) hash = String::cast(source)->Hash(); |
5472 } | 5572 } |
(...skipping 12 matching lines...) Expand all Loading... |
5485 Code* code = shared_info->code(); | 5585 Code* code = shared_info->code(); |
5486 if (code->kind() == Code::OPTIMIZED_FUNCTION) return true; | 5586 if (code->kind() == Code::OPTIMIZED_FUNCTION) return true; |
5487 // If we never ran this (unlikely) then lets try to optimize it. | 5587 // If we never ran this (unlikely) then lets try to optimize it. |
5488 if (code->kind() != Code::FUNCTION) return true; | 5588 if (code->kind() != Code::FUNCTION) return true; |
5489 return code->optimizable(); | 5589 return code->optimizable(); |
5490 } | 5590 } |
5491 | 5591 |
5492 | 5592 |
5493 Object* JSFunction::SetInstancePrototype(Object* value) { | 5593 Object* JSFunction::SetInstancePrototype(Object* value) { |
5494 ASSERT(value->IsJSObject()); | 5594 ASSERT(value->IsJSObject()); |
5495 | 5595 Heap* heap = GetHeap(); |
5496 if (has_initial_map()) { | 5596 if (has_initial_map()) { |
5497 initial_map()->set_prototype(value); | 5597 initial_map()->set_prototype(value); |
5498 } else { | 5598 } else { |
5499 // Put the value in the initial map field until an initial map is | 5599 // Put the value in the initial map field until an initial map is |
5500 // needed. At that point, a new initial map is created and the | 5600 // needed. At that point, a new initial map is created and the |
5501 // prototype is put into the initial map where it belongs. | 5601 // prototype is put into the initial map where it belongs. |
5502 set_prototype_or_initial_map(value); | 5602 set_prototype_or_initial_map(value); |
5503 } | 5603 } |
5504 Heap::ClearInstanceofCache(); | 5604 heap->ClearInstanceofCache(); |
5505 return value; | 5605 return value; |
5506 } | 5606 } |
5507 | 5607 |
5508 | 5608 |
5509 MaybeObject* JSFunction::SetPrototype(Object* value) { | 5609 MaybeObject* JSFunction::SetPrototype(Object* value) { |
5510 ASSERT(should_have_prototype()); | 5610 ASSERT(should_have_prototype()); |
5511 Object* construct_prototype = value; | 5611 Object* construct_prototype = value; |
5512 | 5612 |
5513 // If the value is not a JSObject, store the value in the map's | 5613 // If the value is not a JSObject, store the value in the map's |
5514 // constructor field so it can be accessed. Also, set the prototype | 5614 // constructor field so it can be accessed. Also, set the prototype |
5515 // used for constructing objects to the original object prototype. | 5615 // used for constructing objects to the original object prototype. |
5516 // See ECMA-262 13.2.2. | 5616 // See ECMA-262 13.2.2. |
5517 if (!value->IsJSObject()) { | 5617 if (!value->IsJSObject()) { |
| 5618 Heap* heap = GetHeap(); |
5518 // Copy the map so this does not affect unrelated functions. | 5619 // Copy the map so this does not affect unrelated functions. |
5519 // Remove map transitions because they point to maps with a | 5620 // Remove map transitions because they point to maps with a |
5520 // different prototype. | 5621 // different prototype. |
5521 Object* new_map; | 5622 Object* new_map; |
5522 { MaybeObject* maybe_new_map = map()->CopyDropTransitions(); | 5623 { MaybeObject* maybe_new_map = map()->CopyDropTransitions(); |
5523 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; | 5624 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; |
5524 } | 5625 } |
5525 set_map(Map::cast(new_map)); | 5626 set_map(Map::cast(new_map)); |
5526 map()->set_constructor(value); | 5627 map()->set_constructor(value); |
5527 map()->set_non_instance_prototype(true); | 5628 map()->set_non_instance_prototype(true); |
5528 construct_prototype = | 5629 construct_prototype = |
5529 Top::context()->global_context()->initial_object_prototype(); | 5630 heap->isolate()->context()->global_context()-> |
| 5631 initial_object_prototype(); |
5530 } else { | 5632 } else { |
5531 map()->set_non_instance_prototype(false); | 5633 map()->set_non_instance_prototype(false); |
5532 } | 5634 } |
5533 | 5635 |
5534 return SetInstancePrototype(construct_prototype); | 5636 return SetInstancePrototype(construct_prototype); |
5535 } | 5637 } |
5536 | 5638 |
5537 | 5639 |
5538 Object* JSFunction::RemovePrototype() { | 5640 Object* JSFunction::RemovePrototype() { |
5539 Context* global_context = context()->global_context(); | 5641 Context* global_context = context()->global_context(); |
5540 Map* no_prototype_map = shared()->strict_mode() | 5642 Map* no_prototype_map = shared()->strict_mode() |
5541 ? global_context->strict_mode_function_without_prototype_map() | 5643 ? global_context->strict_mode_function_without_prototype_map() |
5542 : global_context->function_without_prototype_map(); | 5644 : global_context->function_without_prototype_map(); |
5543 | 5645 |
5544 if (map() == no_prototype_map) { | 5646 if (map() == no_prototype_map) { |
5545 // Be idempotent. | 5647 // Be idempotent. |
5546 return this; | 5648 return this; |
5547 } | 5649 } |
5548 | 5650 |
5549 ASSERT(!shared()->strict_mode() || | 5651 ASSERT(!shared()->strict_mode() || |
5550 map() == global_context->strict_mode_function_map()); | 5652 map() == global_context->strict_mode_function_map()); |
5551 ASSERT(shared()->strict_mode() || map() == global_context->function_map()); | 5653 ASSERT(shared()->strict_mode() || map() == global_context->function_map()); |
5552 | 5654 |
5553 set_map(no_prototype_map); | 5655 set_map(no_prototype_map); |
5554 set_prototype_or_initial_map(Heap::the_hole_value()); | 5656 set_prototype_or_initial_map(GetHeap()->the_hole_value()); |
5555 return this; | 5657 return this; |
5556 } | 5658 } |
5557 | 5659 |
5558 | 5660 |
5559 Object* JSFunction::SetInstanceClassName(String* name) { | 5661 Object* JSFunction::SetInstanceClassName(String* name) { |
5560 shared()->set_instance_class_name(name); | 5662 shared()->set_instance_class_name(name); |
5561 return this; | 5663 return this; |
5562 } | 5664 } |
5563 | 5665 |
5564 | 5666 |
5565 void JSFunction::PrintName(FILE* out) { | 5667 void JSFunction::PrintName(FILE* out) { |
5566 SmartPointer<char> name = shared()->DebugName()->ToCString(); | 5668 SmartPointer<char> name = shared()->DebugName()->ToCString(); |
5567 PrintF(out, "%s", *name); | 5669 PrintF(out, "%s", *name); |
5568 } | 5670 } |
5569 | 5671 |
5570 | 5672 |
5571 Context* JSFunction::GlobalContextFromLiterals(FixedArray* literals) { | 5673 Context* JSFunction::GlobalContextFromLiterals(FixedArray* literals) { |
5572 return Context::cast(literals->get(JSFunction::kLiteralGlobalContextIndex)); | 5674 return Context::cast(literals->get(JSFunction::kLiteralGlobalContextIndex)); |
5573 } | 5675 } |
5574 | 5676 |
5575 | 5677 |
5576 MaybeObject* Oddball::Initialize(const char* to_string, Object* to_number) { | 5678 MaybeObject* Oddball::Initialize(const char* to_string, |
| 5679 Object* to_number, |
| 5680 byte kind) { |
5577 Object* symbol; | 5681 Object* symbol; |
5578 { MaybeObject* maybe_symbol = Heap::LookupAsciiSymbol(to_string); | 5682 { MaybeObject* maybe_symbol = |
| 5683 Isolate::Current()->heap()->LookupAsciiSymbol(to_string); |
5579 if (!maybe_symbol->ToObject(&symbol)) return maybe_symbol; | 5684 if (!maybe_symbol->ToObject(&symbol)) return maybe_symbol; |
5580 } | 5685 } |
5581 set_to_string(String::cast(symbol)); | 5686 set_to_string(String::cast(symbol)); |
5582 set_to_number(to_number); | 5687 set_to_number(to_number); |
| 5688 set_kind(kind); |
5583 return this; | 5689 return this; |
5584 } | 5690 } |
5585 | 5691 |
5586 | 5692 |
5587 String* SharedFunctionInfo::DebugName() { | 5693 String* SharedFunctionInfo::DebugName() { |
5588 Object* n = name(); | 5694 Object* n = name(); |
5589 if (!n->IsString() || String::cast(n)->length() == 0) return inferred_name(); | 5695 if (!n->IsString() || String::cast(n)->length() == 0) return inferred_name(); |
5590 return String::cast(n); | 5696 return String::cast(n); |
5591 } | 5697 } |
5592 | 5698 |
5593 | 5699 |
5594 bool SharedFunctionInfo::HasSourceCode() { | 5700 bool SharedFunctionInfo::HasSourceCode() { |
5595 return !script()->IsUndefined() && | 5701 return !script()->IsUndefined() && |
5596 !reinterpret_cast<Script*>(script())->source()->IsUndefined(); | 5702 !reinterpret_cast<Script*>(script())->source()->IsUndefined(); |
5597 } | 5703 } |
5598 | 5704 |
5599 | 5705 |
5600 Object* SharedFunctionInfo::GetSourceCode() { | 5706 Object* SharedFunctionInfo::GetSourceCode() { |
5601 if (!HasSourceCode()) return Heap::undefined_value(); | 5707 Isolate* isolate = GetIsolate(); |
5602 HandleScope scope; | 5708 if (!HasSourceCode()) return isolate->heap()->undefined_value(); |
| 5709 HandleScope scope(isolate); |
5603 Object* source = Script::cast(script())->source(); | 5710 Object* source = Script::cast(script())->source(); |
5604 return *SubString(Handle<String>(String::cast(source)), | 5711 return *SubString(Handle<String>(String::cast(source), isolate), |
5605 start_position(), end_position()); | 5712 start_position(), end_position()); |
5606 } | 5713 } |
5607 | 5714 |
5608 | 5715 |
5609 int SharedFunctionInfo::SourceSize() { | 5716 int SharedFunctionInfo::SourceSize() { |
5610 return end_position() - start_position(); | 5717 return end_position() - start_position(); |
5611 } | 5718 } |
5612 | 5719 |
5613 | 5720 |
5614 int SharedFunctionInfo::CalculateInstanceSize() { | 5721 int SharedFunctionInfo::CalculateInstanceSize() { |
5615 int instance_size = | 5722 int instance_size = |
5616 JSObject::kHeaderSize + | 5723 JSObject::kHeaderSize + |
5617 expected_nof_properties() * kPointerSize; | 5724 expected_nof_properties() * kPointerSize; |
5618 if (instance_size > JSObject::kMaxInstanceSize) { | 5725 if (instance_size > JSObject::kMaxInstanceSize) { |
5619 instance_size = JSObject::kMaxInstanceSize; | 5726 instance_size = JSObject::kMaxInstanceSize; |
5620 } | 5727 } |
5621 return instance_size; | 5728 return instance_size; |
5622 } | 5729 } |
5623 | 5730 |
5624 | 5731 |
5625 int SharedFunctionInfo::CalculateInObjectProperties() { | 5732 int SharedFunctionInfo::CalculateInObjectProperties() { |
5626 return (CalculateInstanceSize() - JSObject::kHeaderSize) / kPointerSize; | 5733 return (CalculateInstanceSize() - JSObject::kHeaderSize) / kPointerSize; |
5627 } | 5734 } |
5628 | 5735 |
5629 | 5736 |
5630 bool SharedFunctionInfo::CanGenerateInlineConstructor(Object* prototype) { | 5737 bool SharedFunctionInfo::CanGenerateInlineConstructor(Object* prototype) { |
| 5738 Heap* heap = GetHeap(); |
| 5739 |
5631 // Check the basic conditions for generating inline constructor code. | 5740 // Check the basic conditions for generating inline constructor code. |
5632 if (!FLAG_inline_new | 5741 if (!FLAG_inline_new |
5633 || !has_only_simple_this_property_assignments() | 5742 || !has_only_simple_this_property_assignments() |
5634 || this_property_assignments_count() == 0) { | 5743 || this_property_assignments_count() == 0) { |
5635 return false; | 5744 return false; |
5636 } | 5745 } |
5637 | 5746 |
5638 // If the prototype is null inline constructors cause no problems. | 5747 // If the prototype is null inline constructors cause no problems. |
5639 if (!prototype->IsJSObject()) { | 5748 if (!prototype->IsJSObject()) { |
5640 ASSERT(prototype->IsNull()); | 5749 ASSERT(prototype->IsNull()); |
5641 return true; | 5750 return true; |
5642 } | 5751 } |
5643 | 5752 |
5644 // Traverse the proposed prototype chain looking for setters for properties of | 5753 // Traverse the proposed prototype chain looking for setters for properties of |
5645 // the same names as are set by the inline constructor. | 5754 // the same names as are set by the inline constructor. |
5646 for (Object* obj = prototype; | 5755 for (Object* obj = prototype; |
5647 obj != Heap::null_value(); | 5756 obj != heap->null_value(); |
5648 obj = obj->GetPrototype()) { | 5757 obj = obj->GetPrototype()) { |
5649 JSObject* js_object = JSObject::cast(obj); | 5758 JSObject* js_object = JSObject::cast(obj); |
5650 for (int i = 0; i < this_property_assignments_count(); i++) { | 5759 for (int i = 0; i < this_property_assignments_count(); i++) { |
5651 LookupResult result; | 5760 LookupResult result; |
5652 String* name = GetThisPropertyAssignmentName(i); | 5761 String* name = GetThisPropertyAssignmentName(i); |
5653 js_object->LocalLookupRealNamedProperty(name, &result); | 5762 js_object->LocalLookupRealNamedProperty(name, &result); |
5654 if (result.IsProperty() && result.type() == CALLBACKS) { | 5763 if (result.IsProperty() && result.type() == CALLBACKS) { |
5655 return false; | 5764 return false; |
5656 } | 5765 } |
5657 } | 5766 } |
(...skipping 15 matching lines...) Expand all Loading... |
5673 FixedArray* assignments) { | 5782 FixedArray* assignments) { |
5674 set_compiler_hints(BooleanBit::set(compiler_hints(), | 5783 set_compiler_hints(BooleanBit::set(compiler_hints(), |
5675 kHasOnlySimpleThisPropertyAssignments, | 5784 kHasOnlySimpleThisPropertyAssignments, |
5676 only_simple_this_property_assignments)); | 5785 only_simple_this_property_assignments)); |
5677 set_this_property_assignments(assignments); | 5786 set_this_property_assignments(assignments); |
5678 set_this_property_assignments_count(assignments->length() / 3); | 5787 set_this_property_assignments_count(assignments->length() / 3); |
5679 } | 5788 } |
5680 | 5789 |
5681 | 5790 |
5682 void SharedFunctionInfo::ClearThisPropertyAssignmentsInfo() { | 5791 void SharedFunctionInfo::ClearThisPropertyAssignmentsInfo() { |
| 5792 Heap* heap = GetHeap(); |
5683 set_compiler_hints(BooleanBit::set(compiler_hints(), | 5793 set_compiler_hints(BooleanBit::set(compiler_hints(), |
5684 kHasOnlySimpleThisPropertyAssignments, | 5794 kHasOnlySimpleThisPropertyAssignments, |
5685 false)); | 5795 false)); |
5686 set_this_property_assignments(Heap::undefined_value()); | 5796 set_this_property_assignments(heap->undefined_value()); |
5687 set_this_property_assignments_count(0); | 5797 set_this_property_assignments_count(0); |
5688 } | 5798 } |
5689 | 5799 |
5690 | 5800 |
5691 String* SharedFunctionInfo::GetThisPropertyAssignmentName(int index) { | 5801 String* SharedFunctionInfo::GetThisPropertyAssignmentName(int index) { |
5692 Object* obj = this_property_assignments(); | 5802 Object* obj = this_property_assignments(); |
5693 ASSERT(obj->IsFixedArray()); | 5803 ASSERT(obj->IsFixedArray()); |
5694 ASSERT(index < this_property_assignments_count()); | 5804 ASSERT(index < this_property_assignments_count()); |
5695 obj = FixedArray::cast(obj)->get(index * 3); | 5805 obj = FixedArray::cast(obj)->get(index * 3); |
5696 ASSERT(obj->IsString()); | 5806 ASSERT(obj->IsString()); |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5821 if (Serializer::enabled()) return; | 5931 if (Serializer::enabled()) return; |
5822 | 5932 |
5823 if (map->unused_property_fields() == 0) return; | 5933 if (map->unused_property_fields() == 0) return; |
5824 | 5934 |
5825 // Nonzero counter is a leftover from the previous attempt interrupted | 5935 // Nonzero counter is a leftover from the previous attempt interrupted |
5826 // by GC, keep it. | 5936 // by GC, keep it. |
5827 if (construction_count() == 0) { | 5937 if (construction_count() == 0) { |
5828 set_construction_count(kGenerousAllocationCount); | 5938 set_construction_count(kGenerousAllocationCount); |
5829 } | 5939 } |
5830 set_initial_map(map); | 5940 set_initial_map(map); |
5831 ASSERT_EQ(Builtins::builtin(Builtins::JSConstructStubGeneric), | 5941 Builtins* builtins = map->heap()->isolate()->builtins(); |
| 5942 ASSERT_EQ(builtins->builtin(Builtins::JSConstructStubGeneric), |
5832 construct_stub()); | 5943 construct_stub()); |
5833 set_construct_stub(Builtins::builtin(Builtins::JSConstructStubCountdown)); | 5944 set_construct_stub(builtins->builtin(Builtins::JSConstructStubCountdown)); |
5834 } | 5945 } |
5835 | 5946 |
5836 | 5947 |
5837 // Called from GC, hence reinterpret_cast and unchecked accessors. | 5948 // Called from GC, hence reinterpret_cast and unchecked accessors. |
5838 void SharedFunctionInfo::DetachInitialMap() { | 5949 void SharedFunctionInfo::DetachInitialMap() { |
5839 Map* map = reinterpret_cast<Map*>(initial_map()); | 5950 Map* map = reinterpret_cast<Map*>(initial_map()); |
5840 | 5951 |
5841 // Make the map remember to restore the link if it survives the GC. | 5952 // Make the map remember to restore the link if it survives the GC. |
5842 map->set_bit_field2( | 5953 map->set_bit_field2( |
5843 map->bit_field2() | (1 << Map::kAttachedToSharedFunctionInfo)); | 5954 map->bit_field2() | (1 << Map::kAttachedToSharedFunctionInfo)); |
5844 | 5955 |
5845 // Undo state changes made by StartInobjectTracking (except the | 5956 // Undo state changes made by StartInobjectTracking (except the |
5846 // construction_count). This way if the initial map does not survive the GC | 5957 // construction_count). This way if the initial map does not survive the GC |
5847 // then StartInobjectTracking will be called again the next time the | 5958 // then StartInobjectTracking will be called again the next time the |
5848 // constructor is called. The countdown will continue and (possibly after | 5959 // constructor is called. The countdown will continue and (possibly after |
5849 // several more GCs) CompleteInobjectSlackTracking will eventually be called. | 5960 // several more GCs) CompleteInobjectSlackTracking will eventually be called. |
5850 set_initial_map(Heap::raw_unchecked_undefined_value()); | 5961 set_initial_map(map->heap()->raw_unchecked_undefined_value()); |
5851 ASSERT_EQ(Builtins::builtin(Builtins::JSConstructStubCountdown), | 5962 Builtins* builtins = map->heap()->isolate()->builtins(); |
| 5963 ASSERT_EQ(builtins->builtin(Builtins::JSConstructStubCountdown), |
5852 *RawField(this, kConstructStubOffset)); | 5964 *RawField(this, kConstructStubOffset)); |
5853 set_construct_stub(Builtins::builtin(Builtins::JSConstructStubGeneric)); | 5965 set_construct_stub(builtins->builtin(Builtins::JSConstructStubGeneric)); |
5854 // It is safe to clear the flag: it will be set again if the map is live. | 5966 // It is safe to clear the flag: it will be set again if the map is live. |
5855 set_live_objects_may_exist(false); | 5967 set_live_objects_may_exist(false); |
5856 } | 5968 } |
5857 | 5969 |
5858 | 5970 |
5859 // Called from GC, hence reinterpret_cast and unchecked accessors. | 5971 // Called from GC, hence reinterpret_cast and unchecked accessors. |
5860 void SharedFunctionInfo::AttachInitialMap(Map* map) { | 5972 void SharedFunctionInfo::AttachInitialMap(Map* map) { |
5861 map->set_bit_field2( | 5973 map->set_bit_field2( |
5862 map->bit_field2() & ~(1 << Map::kAttachedToSharedFunctionInfo)); | 5974 map->bit_field2() & ~(1 << Map::kAttachedToSharedFunctionInfo)); |
5863 | 5975 |
5864 // Resume inobject slack tracking. | 5976 // Resume inobject slack tracking. |
5865 set_initial_map(map); | 5977 set_initial_map(map); |
5866 ASSERT_EQ(Builtins::builtin(Builtins::JSConstructStubGeneric), | 5978 Builtins* builtins = map->heap()->isolate()->builtins(); |
| 5979 ASSERT_EQ(builtins->builtin(Builtins::JSConstructStubGeneric), |
5867 *RawField(this, kConstructStubOffset)); | 5980 *RawField(this, kConstructStubOffset)); |
5868 set_construct_stub(Builtins::builtin(Builtins::JSConstructStubCountdown)); | 5981 set_construct_stub(builtins->builtin(Builtins::JSConstructStubCountdown)); |
5869 // The map survived the gc, so there may be objects referencing it. | 5982 // The map survived the gc, so there may be objects referencing it. |
5870 set_live_objects_may_exist(true); | 5983 set_live_objects_may_exist(true); |
5871 } | 5984 } |
5872 | 5985 |
5873 | 5986 |
5874 static void GetMinInobjectSlack(Map* map, void* data) { | 5987 static void GetMinInobjectSlack(Map* map, void* data) { |
5875 int slack = map->unused_property_fields(); | 5988 int slack = map->unused_property_fields(); |
5876 if (*reinterpret_cast<int*>(data) > slack) { | 5989 if (*reinterpret_cast<int*>(data) > slack) { |
5877 *reinterpret_cast<int*>(data) = slack; | 5990 *reinterpret_cast<int*>(data) = slack; |
5878 } | 5991 } |
5879 } | 5992 } |
5880 | 5993 |
5881 | 5994 |
5882 static void ShrinkInstanceSize(Map* map, void* data) { | 5995 static void ShrinkInstanceSize(Map* map, void* data) { |
5883 int slack = *reinterpret_cast<int*>(data); | 5996 int slack = *reinterpret_cast<int*>(data); |
5884 map->set_inobject_properties(map->inobject_properties() - slack); | 5997 map->set_inobject_properties(map->inobject_properties() - slack); |
5885 map->set_unused_property_fields(map->unused_property_fields() - slack); | 5998 map->set_unused_property_fields(map->unused_property_fields() - slack); |
5886 map->set_instance_size(map->instance_size() - slack * kPointerSize); | 5999 map->set_instance_size(map->instance_size() - slack * kPointerSize); |
5887 | 6000 |
5888 // Visitor id might depend on the instance size, recalculate it. | 6001 // Visitor id might depend on the instance size, recalculate it. |
5889 map->set_visitor_id(StaticVisitorBase::GetVisitorId(map)); | 6002 map->set_visitor_id(StaticVisitorBase::GetVisitorId(map)); |
5890 } | 6003 } |
5891 | 6004 |
5892 | 6005 |
5893 void SharedFunctionInfo::CompleteInobjectSlackTracking() { | 6006 void SharedFunctionInfo::CompleteInobjectSlackTracking() { |
5894 ASSERT(live_objects_may_exist() && IsInobjectSlackTrackingInProgress()); | 6007 ASSERT(live_objects_may_exist() && IsInobjectSlackTrackingInProgress()); |
5895 Map* map = Map::cast(initial_map()); | 6008 Map* map = Map::cast(initial_map()); |
5896 | 6009 |
5897 set_initial_map(Heap::undefined_value()); | 6010 Heap* heap = map->heap(); |
5898 ASSERT_EQ(Builtins::builtin(Builtins::JSConstructStubCountdown), | 6011 set_initial_map(heap->undefined_value()); |
| 6012 Builtins* builtins = heap->isolate()->builtins(); |
| 6013 ASSERT_EQ(builtins->builtin(Builtins::JSConstructStubCountdown), |
5899 construct_stub()); | 6014 construct_stub()); |
5900 set_construct_stub(Builtins::builtin(Builtins::JSConstructStubGeneric)); | 6015 set_construct_stub(builtins->builtin(Builtins::JSConstructStubGeneric)); |
5901 | 6016 |
5902 int slack = map->unused_property_fields(); | 6017 int slack = map->unused_property_fields(); |
5903 map->TraverseTransitionTree(&GetMinInobjectSlack, &slack); | 6018 map->TraverseTransitionTree(&GetMinInobjectSlack, &slack); |
5904 if (slack != 0) { | 6019 if (slack != 0) { |
5905 // Resize the initial map and all maps in its transition tree. | 6020 // Resize the initial map and all maps in its transition tree. |
5906 map->TraverseTransitionTree(&ShrinkInstanceSize, &slack); | 6021 map->TraverseTransitionTree(&ShrinkInstanceSize, &slack); |
5907 // Give the correct expected_nof_properties to initial maps created later. | 6022 // Give the correct expected_nof_properties to initial maps created later. |
5908 ASSERT(expected_nof_properties() >= slack); | 6023 ASSERT(expected_nof_properties() >= slack); |
5909 set_expected_nof_properties(expected_nof_properties() - slack); | 6024 set_expected_nof_properties(expected_nof_properties() - slack); |
5910 } | 6025 } |
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
5947 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && | 6062 (RelocInfo::IsDebugBreakSlot(rinfo->rmode()) && |
5948 rinfo->IsPatchedDebugBreakSlotSequence())); | 6063 rinfo->IsPatchedDebugBreakSlotSequence())); |
5949 Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address()); | 6064 Object* target = Code::GetCodeFromTargetAddress(rinfo->call_address()); |
5950 Object* old_target = target; | 6065 Object* old_target = target; |
5951 VisitPointer(&target); | 6066 VisitPointer(&target); |
5952 CHECK_EQ(target, old_target); // VisitPointer doesn't change Code* *target. | 6067 CHECK_EQ(target, old_target); // VisitPointer doesn't change Code* *target. |
5953 } | 6068 } |
5954 | 6069 |
5955 | 6070 |
5956 void Code::InvalidateRelocation() { | 6071 void Code::InvalidateRelocation() { |
5957 HandleScope scope; | 6072 set_relocation_info(GetHeap()->empty_byte_array()); |
5958 set_relocation_info(Heap::empty_byte_array()); | |
5959 } | 6073 } |
5960 | 6074 |
5961 | 6075 |
5962 void Code::Relocate(intptr_t delta) { | 6076 void Code::Relocate(intptr_t delta) { |
5963 for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) { | 6077 for (RelocIterator it(this, RelocInfo::kApplyMask); !it.done(); it.next()) { |
5964 it.rinfo()->apply(delta); | 6078 it.rinfo()->apply(delta); |
5965 } | 6079 } |
5966 CPU::FlushICache(instruction_start(), instruction_size()); | 6080 CPU::FlushICache(instruction_start(), instruction_size()); |
5967 } | 6081 } |
5968 | 6082 |
(...skipping 425 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6394 | 6508 |
6395 PrintF("RelocInfo (size = %d)\n", relocation_size()); | 6509 PrintF("RelocInfo (size = %d)\n", relocation_size()); |
6396 for (RelocIterator it(this); !it.done(); it.next()) it.rinfo()->Print(out); | 6510 for (RelocIterator it(this); !it.done(); it.next()) it.rinfo()->Print(out); |
6397 PrintF(out, "\n"); | 6511 PrintF(out, "\n"); |
6398 } | 6512 } |
6399 #endif // ENABLE_DISASSEMBLER | 6513 #endif // ENABLE_DISASSEMBLER |
6400 | 6514 |
6401 | 6515 |
6402 MaybeObject* JSObject::SetFastElementsCapacityAndLength(int capacity, | 6516 MaybeObject* JSObject::SetFastElementsCapacityAndLength(int capacity, |
6403 int length) { | 6517 int length) { |
| 6518 Heap* heap = GetHeap(); |
6404 // We should never end in here with a pixel or external array. | 6519 // We should never end in here with a pixel or external array. |
6405 ASSERT(!HasExternalArrayElements()); | 6520 ASSERT(!HasExternalArrayElements()); |
6406 | 6521 |
6407 Object* obj; | 6522 Object* obj; |
6408 { MaybeObject* maybe_obj = Heap::AllocateFixedArrayWithHoles(capacity); | 6523 { MaybeObject* maybe_obj = heap->AllocateFixedArrayWithHoles(capacity); |
6409 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 6524 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
6410 } | 6525 } |
6411 FixedArray* elems = FixedArray::cast(obj); | 6526 FixedArray* elems = FixedArray::cast(obj); |
6412 | 6527 |
6413 { MaybeObject* maybe_obj = map()->GetFastElementsMap(); | 6528 { MaybeObject* maybe_obj = map()->GetFastElementsMap(); |
6414 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 6529 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
6415 } | 6530 } |
6416 Map* new_map = Map::cast(obj); | 6531 Map* new_map = Map::cast(obj); |
6417 | 6532 |
6418 AssertNoAllocation no_gc; | 6533 AssertNoAllocation no_gc; |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6485 } | 6600 } |
6486 default: | 6601 default: |
6487 UNREACHABLE(); | 6602 UNREACHABLE(); |
6488 break; | 6603 break; |
6489 } | 6604 } |
6490 return this; | 6605 return this; |
6491 } | 6606 } |
6492 | 6607 |
6493 | 6608 |
6494 MaybeObject* JSArray::Initialize(int capacity) { | 6609 MaybeObject* JSArray::Initialize(int capacity) { |
| 6610 Heap* heap = GetHeap(); |
6495 ASSERT(capacity >= 0); | 6611 ASSERT(capacity >= 0); |
6496 set_length(Smi::FromInt(0)); | 6612 set_length(Smi::FromInt(0)); |
6497 FixedArray* new_elements; | 6613 FixedArray* new_elements; |
6498 if (capacity == 0) { | 6614 if (capacity == 0) { |
6499 new_elements = Heap::empty_fixed_array(); | 6615 new_elements = heap->empty_fixed_array(); |
6500 } else { | 6616 } else { |
6501 Object* obj; | 6617 Object* obj; |
6502 { MaybeObject* maybe_obj = Heap::AllocateFixedArrayWithHoles(capacity); | 6618 { MaybeObject* maybe_obj = heap->AllocateFixedArrayWithHoles(capacity); |
6503 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 6619 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
6504 } | 6620 } |
6505 new_elements = FixedArray::cast(obj); | 6621 new_elements = FixedArray::cast(obj); |
6506 } | 6622 } |
6507 set_elements(new_elements); | 6623 set_elements(new_elements); |
6508 return this; | 6624 return this; |
6509 } | 6625 } |
6510 | 6626 |
6511 | 6627 |
6512 void JSArray::Expand(int required_size) { | 6628 void JSArray::Expand(int required_size) { |
6513 Handle<JSArray> self(this); | 6629 Handle<JSArray> self(this); |
6514 Handle<FixedArray> old_backing(FixedArray::cast(elements())); | 6630 Handle<FixedArray> old_backing(FixedArray::cast(elements())); |
6515 int old_size = old_backing->length(); | 6631 int old_size = old_backing->length(); |
6516 int new_size = required_size > old_size ? required_size : old_size; | 6632 int new_size = required_size > old_size ? required_size : old_size; |
6517 Handle<FixedArray> new_backing = Factory::NewFixedArray(new_size); | 6633 Handle<FixedArray> new_backing = FACTORY->NewFixedArray(new_size); |
6518 // Can't use this any more now because we may have had a GC! | 6634 // Can't use this any more now because we may have had a GC! |
6519 for (int i = 0; i < old_size; i++) new_backing->set(i, old_backing->get(i)); | 6635 for (int i = 0; i < old_size; i++) new_backing->set(i, old_backing->get(i)); |
6520 self->SetContent(*new_backing); | 6636 self->SetContent(*new_backing); |
6521 } | 6637 } |
6522 | 6638 |
6523 | 6639 |
6524 static Failure* ArrayLengthRangeError() { | 6640 static Failure* ArrayLengthRangeError(Heap* heap) { |
6525 HandleScope scope; | 6641 HandleScope scope; |
6526 return Top::Throw(*Factory::NewRangeError("invalid_array_length", | 6642 return heap->isolate()->Throw( |
6527 HandleVector<Object>(NULL, 0))); | 6643 *FACTORY->NewRangeError("invalid_array_length", |
| 6644 HandleVector<Object>(NULL, 0))); |
6528 } | 6645 } |
6529 | 6646 |
6530 | 6647 |
6531 MaybeObject* JSObject::SetElementsLength(Object* len) { | 6648 MaybeObject* JSObject::SetElementsLength(Object* len) { |
| 6649 Heap* heap = GetHeap(); |
6532 // We should never end in here with a pixel or external array. | 6650 // We should never end in here with a pixel or external array. |
6533 ASSERT(AllowsSetElementsLength()); | 6651 ASSERT(AllowsSetElementsLength()); |
6534 | 6652 |
6535 MaybeObject* maybe_smi_length = len->ToSmi(); | 6653 MaybeObject* maybe_smi_length = len->ToSmi(); |
6536 Object* smi_length = Smi::FromInt(0); | 6654 Object* smi_length = Smi::FromInt(0); |
6537 if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) { | 6655 if (maybe_smi_length->ToObject(&smi_length) && smi_length->IsSmi()) { |
6538 const int value = Smi::cast(smi_length)->value(); | 6656 const int value = Smi::cast(smi_length)->value(); |
6539 if (value < 0) return ArrayLengthRangeError(); | 6657 if (value < 0) return ArrayLengthRangeError(heap); |
6540 switch (GetElementsKind()) { | 6658 switch (GetElementsKind()) { |
6541 case FAST_ELEMENTS: { | 6659 case FAST_ELEMENTS: { |
6542 int old_capacity = FixedArray::cast(elements())->length(); | 6660 int old_capacity = FixedArray::cast(elements())->length(); |
6543 if (value <= old_capacity) { | 6661 if (value <= old_capacity) { |
6544 if (IsJSArray()) { | 6662 if (IsJSArray()) { |
6545 Object* obj; | 6663 Object* obj; |
6546 { MaybeObject* maybe_obj = EnsureWritableFastElements(); | 6664 { MaybeObject* maybe_obj = EnsureWritableFastElements(); |
6547 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 6665 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
6548 } | 6666 } |
6549 int old_length = FastD2I(JSArray::cast(this)->length()->Number()); | 6667 int old_length = FastD2I(JSArray::cast(this)->length()->Number()); |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6595 break; | 6713 break; |
6596 } | 6714 } |
6597 } | 6715 } |
6598 | 6716 |
6599 // General slow case. | 6717 // General slow case. |
6600 if (len->IsNumber()) { | 6718 if (len->IsNumber()) { |
6601 uint32_t length; | 6719 uint32_t length; |
6602 if (len->ToArrayIndex(&length)) { | 6720 if (len->ToArrayIndex(&length)) { |
6603 return SetSlowElements(len); | 6721 return SetSlowElements(len); |
6604 } else { | 6722 } else { |
6605 return ArrayLengthRangeError(); | 6723 return ArrayLengthRangeError(heap); |
6606 } | 6724 } |
6607 } | 6725 } |
6608 | 6726 |
6609 // len is not a number so make the array size one and | 6727 // len is not a number so make the array size one and |
6610 // set only element to len. | 6728 // set only element to len. |
6611 Object* obj; | 6729 Object* obj; |
6612 { MaybeObject* maybe_obj = Heap::AllocateFixedArray(1); | 6730 { MaybeObject* maybe_obj = heap->AllocateFixedArray(1); |
6613 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 6731 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
6614 } | 6732 } |
6615 FixedArray::cast(obj)->set(0, len); | 6733 FixedArray::cast(obj)->set(0, len); |
6616 if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(1)); | 6734 if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(1)); |
6617 set_elements(FixedArray::cast(obj)); | 6735 set_elements(FixedArray::cast(obj)); |
6618 return this; | 6736 return this; |
6619 } | 6737 } |
6620 | 6738 |
6621 | 6739 |
6622 MaybeObject* JSObject::SetPrototype(Object* value, | 6740 MaybeObject* JSObject::SetPrototype(Object* value, |
6623 bool skip_hidden_prototypes) { | 6741 bool skip_hidden_prototypes) { |
| 6742 Heap* heap = GetHeap(); |
6624 // Silently ignore the change if value is not a JSObject or null. | 6743 // Silently ignore the change if value is not a JSObject or null. |
6625 // SpiderMonkey behaves this way. | 6744 // SpiderMonkey behaves this way. |
6626 if (!value->IsJSObject() && !value->IsNull()) return value; | 6745 if (!value->IsJSObject() && !value->IsNull()) return value; |
6627 | 6746 |
6628 // Before we can set the prototype we need to be sure | 6747 // Before we can set the prototype we need to be sure |
6629 // prototype cycles are prevented. | 6748 // prototype cycles are prevented. |
6630 // It is sufficient to validate that the receiver is not in the new prototype | 6749 // It is sufficient to validate that the receiver is not in the new prototype |
6631 // chain. | 6750 // chain. |
6632 for (Object* pt = value; pt != Heap::null_value(); pt = pt->GetPrototype()) { | 6751 for (Object* pt = value; pt != heap->null_value(); pt = pt->GetPrototype()) { |
6633 if (JSObject::cast(pt) == this) { | 6752 if (JSObject::cast(pt) == this) { |
6634 // Cycle detected. | 6753 // Cycle detected. |
6635 HandleScope scope; | 6754 HandleScope scope; |
6636 return Top::Throw(*Factory::NewError("cyclic_proto", | 6755 return heap->isolate()->Throw( |
6637 HandleVector<Object>(NULL, 0))); | 6756 *FACTORY->NewError("cyclic_proto", HandleVector<Object>(NULL, 0))); |
6638 } | 6757 } |
6639 } | 6758 } |
6640 | 6759 |
6641 JSObject* real_receiver = this; | 6760 JSObject* real_receiver = this; |
6642 | 6761 |
6643 if (skip_hidden_prototypes) { | 6762 if (skip_hidden_prototypes) { |
6644 // Find the first object in the chain whose prototype object is not | 6763 // Find the first object in the chain whose prototype object is not |
6645 // hidden and set the new prototype on that object. | 6764 // hidden and set the new prototype on that object. |
6646 Object* current_proto = real_receiver->GetPrototype(); | 6765 Object* current_proto = real_receiver->GetPrototype(); |
6647 while (current_proto->IsJSObject() && | 6766 while (current_proto->IsJSObject() && |
6648 JSObject::cast(current_proto)->map()->is_hidden_prototype()) { | 6767 JSObject::cast(current_proto)->map()->is_hidden_prototype()) { |
6649 real_receiver = JSObject::cast(current_proto); | 6768 real_receiver = JSObject::cast(current_proto); |
6650 current_proto = current_proto->GetPrototype(); | 6769 current_proto = current_proto->GetPrototype(); |
6651 } | 6770 } |
6652 } | 6771 } |
6653 | 6772 |
6654 // Set the new prototype of the object. | 6773 // Set the new prototype of the object. |
6655 Object* new_map; | 6774 Object* new_map; |
6656 { MaybeObject* maybe_new_map = real_receiver->map()->CopyDropTransitions(); | 6775 { MaybeObject* maybe_new_map = real_receiver->map()->CopyDropTransitions(); |
6657 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; | 6776 if (!maybe_new_map->ToObject(&new_map)) return maybe_new_map; |
6658 } | 6777 } |
6659 Map::cast(new_map)->set_prototype(value); | 6778 Map::cast(new_map)->set_prototype(value); |
6660 real_receiver->set_map(Map::cast(new_map)); | 6779 real_receiver->set_map(Map::cast(new_map)); |
6661 | 6780 |
6662 Heap::ClearInstanceofCache(); | 6781 heap->ClearInstanceofCache(); |
6663 | 6782 |
6664 return value; | 6783 return value; |
6665 } | 6784 } |
6666 | 6785 |
6667 | 6786 |
6668 bool JSObject::HasElementPostInterceptor(JSObject* receiver, uint32_t index) { | 6787 bool JSObject::HasElementPostInterceptor(JSObject* receiver, uint32_t index) { |
6669 switch (GetElementsKind()) { | 6788 switch (GetElementsKind()) { |
6670 case FAST_ELEMENTS: { | 6789 case FAST_ELEMENTS: { |
6671 uint32_t length = IsJSArray() ? | 6790 uint32_t length = IsJSArray() ? |
6672 static_cast<uint32_t> | 6791 static_cast<uint32_t> |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6707 } | 6826 } |
6708 default: | 6827 default: |
6709 UNREACHABLE(); | 6828 UNREACHABLE(); |
6710 break; | 6829 break; |
6711 } | 6830 } |
6712 | 6831 |
6713 // Handle [] on String objects. | 6832 // Handle [] on String objects. |
6714 if (this->IsStringObjectWithCharacterAt(index)) return true; | 6833 if (this->IsStringObjectWithCharacterAt(index)) return true; |
6715 | 6834 |
6716 Object* pt = GetPrototype(); | 6835 Object* pt = GetPrototype(); |
6717 if (pt == Heap::null_value()) return false; | 6836 if (pt->IsNull()) return false; |
6718 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); | 6837 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); |
6719 } | 6838 } |
6720 | 6839 |
6721 | 6840 |
6722 bool JSObject::HasElementWithInterceptor(JSObject* receiver, uint32_t index) { | 6841 bool JSObject::HasElementWithInterceptor(JSObject* receiver, uint32_t index) { |
| 6842 Isolate* isolate = GetIsolate(); |
6723 // Make sure that the top context does not change when doing | 6843 // Make sure that the top context does not change when doing |
6724 // callbacks or interceptor calls. | 6844 // callbacks or interceptor calls. |
6725 AssertNoContextChange ncc; | 6845 AssertNoContextChange ncc; |
6726 HandleScope scope; | 6846 HandleScope scope(isolate); |
6727 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); | 6847 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); |
6728 Handle<JSObject> receiver_handle(receiver); | 6848 Handle<JSObject> receiver_handle(receiver); |
6729 Handle<JSObject> holder_handle(this); | 6849 Handle<JSObject> holder_handle(this); |
6730 CustomArguments args(interceptor->data(), receiver, this); | 6850 CustomArguments args(isolate, interceptor->data(), receiver, this); |
6731 v8::AccessorInfo info(args.end()); | 6851 v8::AccessorInfo info(args.end()); |
6732 if (!interceptor->query()->IsUndefined()) { | 6852 if (!interceptor->query()->IsUndefined()) { |
6733 v8::IndexedPropertyQuery query = | 6853 v8::IndexedPropertyQuery query = |
6734 v8::ToCData<v8::IndexedPropertyQuery>(interceptor->query()); | 6854 v8::ToCData<v8::IndexedPropertyQuery>(interceptor->query()); |
6735 LOG(ApiIndexedPropertyAccess("interceptor-indexed-has", this, index)); | 6855 LOG(isolate, |
| 6856 ApiIndexedPropertyAccess("interceptor-indexed-has", this, index)); |
6736 v8::Handle<v8::Integer> result; | 6857 v8::Handle<v8::Integer> result; |
6737 { | 6858 { |
6738 // Leaving JavaScript. | 6859 // Leaving JavaScript. |
6739 VMState state(EXTERNAL); | 6860 VMState state(isolate, EXTERNAL); |
6740 result = query(index, info); | 6861 result = query(index, info); |
6741 } | 6862 } |
6742 if (!result.IsEmpty()) { | 6863 if (!result.IsEmpty()) { |
6743 ASSERT(result->IsInt32()); | 6864 ASSERT(result->IsInt32()); |
6744 return true; // absence of property is signaled by empty handle. | 6865 return true; // absence of property is signaled by empty handle. |
6745 } | 6866 } |
6746 } else if (!interceptor->getter()->IsUndefined()) { | 6867 } else if (!interceptor->getter()->IsUndefined()) { |
6747 v8::IndexedPropertyGetter getter = | 6868 v8::IndexedPropertyGetter getter = |
6748 v8::ToCData<v8::IndexedPropertyGetter>(interceptor->getter()); | 6869 v8::ToCData<v8::IndexedPropertyGetter>(interceptor->getter()); |
6749 LOG(ApiIndexedPropertyAccess("interceptor-indexed-has-get", this, index)); | 6870 LOG(isolate, |
| 6871 ApiIndexedPropertyAccess("interceptor-indexed-has-get", this, index)); |
6750 v8::Handle<v8::Value> result; | 6872 v8::Handle<v8::Value> result; |
6751 { | 6873 { |
6752 // Leaving JavaScript. | 6874 // Leaving JavaScript. |
6753 VMState state(EXTERNAL); | 6875 VMState state(isolate, EXTERNAL); |
6754 result = getter(index, info); | 6876 result = getter(index, info); |
6755 } | 6877 } |
6756 if (!result.IsEmpty()) return true; | 6878 if (!result.IsEmpty()) return true; |
6757 } | 6879 } |
6758 return holder_handle->HasElementPostInterceptor(*receiver_handle, index); | 6880 return holder_handle->HasElementPostInterceptor(*receiver_handle, index); |
6759 } | 6881 } |
6760 | 6882 |
6761 | 6883 |
6762 JSObject::LocalElementType JSObject::HasLocalElement(uint32_t index) { | 6884 JSObject::LocalElementType JSObject::HasLocalElement(uint32_t index) { |
| 6885 Heap* heap = GetHeap(); |
| 6886 |
6763 // Check access rights if needed. | 6887 // Check access rights if needed. |
6764 if (IsAccessCheckNeeded() && | 6888 if (IsAccessCheckNeeded() && |
6765 !Top::MayIndexedAccess(this, index, v8::ACCESS_HAS)) { | 6889 !heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { |
6766 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 6890 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
6767 return UNDEFINED_ELEMENT; | 6891 return UNDEFINED_ELEMENT; |
6768 } | 6892 } |
6769 | 6893 |
6770 if (IsJSGlobalProxy()) { | 6894 if (IsJSGlobalProxy()) { |
6771 Object* proto = GetPrototype(); | 6895 Object* proto = GetPrototype(); |
6772 if (proto->IsNull()) return UNDEFINED_ELEMENT; | 6896 if (proto->IsNull()) return UNDEFINED_ELEMENT; |
6773 ASSERT(proto->IsJSGlobalObject()); | 6897 ASSERT(proto->IsJSGlobalObject()); |
6774 return JSObject::cast(proto)->HasLocalElement(index); | 6898 return JSObject::cast(proto)->HasLocalElement(index); |
6775 } | 6899 } |
6776 | 6900 |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6823 default: | 6947 default: |
6824 UNREACHABLE(); | 6948 UNREACHABLE(); |
6825 break; | 6949 break; |
6826 } | 6950 } |
6827 | 6951 |
6828 return UNDEFINED_ELEMENT; | 6952 return UNDEFINED_ELEMENT; |
6829 } | 6953 } |
6830 | 6954 |
6831 | 6955 |
6832 bool JSObject::HasElementWithReceiver(JSObject* receiver, uint32_t index) { | 6956 bool JSObject::HasElementWithReceiver(JSObject* receiver, uint32_t index) { |
| 6957 Heap* heap = GetHeap(); |
| 6958 |
6833 // Check access rights if needed. | 6959 // Check access rights if needed. |
6834 if (IsAccessCheckNeeded() && | 6960 if (IsAccessCheckNeeded() && |
6835 !Top::MayIndexedAccess(this, index, v8::ACCESS_HAS)) { | 6961 !heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { |
6836 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 6962 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
6837 return false; | 6963 return false; |
6838 } | 6964 } |
6839 | 6965 |
6840 // Check for lookup interceptor | 6966 // Check for lookup interceptor |
6841 if (HasIndexedInterceptor()) { | 6967 if (HasIndexedInterceptor()) { |
6842 return HasElementWithInterceptor(receiver, index); | 6968 return HasElementWithInterceptor(receiver, index); |
6843 } | 6969 } |
6844 | 6970 |
6845 switch (GetElementsKind()) { | 6971 switch (GetElementsKind()) { |
6846 case FAST_ELEMENTS: { | 6972 case FAST_ELEMENTS: { |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6881 } | 7007 } |
6882 default: | 7008 default: |
6883 UNREACHABLE(); | 7009 UNREACHABLE(); |
6884 break; | 7010 break; |
6885 } | 7011 } |
6886 | 7012 |
6887 // Handle [] on String objects. | 7013 // Handle [] on String objects. |
6888 if (this->IsStringObjectWithCharacterAt(index)) return true; | 7014 if (this->IsStringObjectWithCharacterAt(index)) return true; |
6889 | 7015 |
6890 Object* pt = GetPrototype(); | 7016 Object* pt = GetPrototype(); |
6891 if (pt == Heap::null_value()) return false; | 7017 if (pt->IsNull()) return false; |
6892 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); | 7018 return JSObject::cast(pt)->HasElementWithReceiver(receiver, index); |
6893 } | 7019 } |
6894 | 7020 |
6895 | 7021 |
6896 MaybeObject* JSObject::SetElementWithInterceptor(uint32_t index, | 7022 MaybeObject* JSObject::SetElementWithInterceptor(uint32_t index, |
6897 Object* value, | 7023 Object* value, |
6898 StrictModeFlag strict_mode, | 7024 StrictModeFlag strict_mode, |
6899 bool check_prototype) { | 7025 bool check_prototype) { |
| 7026 Isolate* isolate = GetIsolate(); |
6900 // Make sure that the top context does not change when doing | 7027 // Make sure that the top context does not change when doing |
6901 // callbacks or interceptor calls. | 7028 // callbacks or interceptor calls. |
6902 AssertNoContextChange ncc; | 7029 AssertNoContextChange ncc; |
6903 HandleScope scope; | 7030 HandleScope scope(isolate); |
6904 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); | 7031 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); |
6905 Handle<JSObject> this_handle(this); | 7032 Handle<JSObject> this_handle(this); |
6906 Handle<Object> value_handle(value); | 7033 Handle<Object> value_handle(value, isolate); |
6907 if (!interceptor->setter()->IsUndefined()) { | 7034 if (!interceptor->setter()->IsUndefined()) { |
6908 v8::IndexedPropertySetter setter = | 7035 v8::IndexedPropertySetter setter = |
6909 v8::ToCData<v8::IndexedPropertySetter>(interceptor->setter()); | 7036 v8::ToCData<v8::IndexedPropertySetter>(interceptor->setter()); |
6910 LOG(ApiIndexedPropertyAccess("interceptor-indexed-set", this, index)); | 7037 LOG(isolate, |
6911 CustomArguments args(interceptor->data(), this, this); | 7038 ApiIndexedPropertyAccess("interceptor-indexed-set", this, index)); |
| 7039 CustomArguments args(isolate, interceptor->data(), this, this); |
6912 v8::AccessorInfo info(args.end()); | 7040 v8::AccessorInfo info(args.end()); |
6913 v8::Handle<v8::Value> result; | 7041 v8::Handle<v8::Value> result; |
6914 { | 7042 { |
6915 // Leaving JavaScript. | 7043 // Leaving JavaScript. |
6916 VMState state(EXTERNAL); | 7044 VMState state(isolate, EXTERNAL); |
6917 result = setter(index, v8::Utils::ToLocal(value_handle), info); | 7045 result = setter(index, v8::Utils::ToLocal(value_handle), info); |
6918 } | 7046 } |
6919 RETURN_IF_SCHEDULED_EXCEPTION(); | 7047 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
6920 if (!result.IsEmpty()) return *value_handle; | 7048 if (!result.IsEmpty()) return *value_handle; |
6921 } | 7049 } |
6922 MaybeObject* raw_result = | 7050 MaybeObject* raw_result = |
6923 this_handle->SetElementWithoutInterceptor(index, | 7051 this_handle->SetElementWithoutInterceptor(index, |
6924 *value_handle, | 7052 *value_handle, |
6925 strict_mode, | 7053 strict_mode, |
6926 check_prototype); | 7054 check_prototype); |
6927 RETURN_IF_SCHEDULED_EXCEPTION(); | 7055 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
6928 return raw_result; | 7056 return raw_result; |
6929 } | 7057 } |
6930 | 7058 |
6931 | 7059 |
6932 MaybeObject* JSObject::GetElementWithCallback(Object* receiver, | 7060 MaybeObject* JSObject::GetElementWithCallback(Object* receiver, |
6933 Object* structure, | 7061 Object* structure, |
6934 uint32_t index, | 7062 uint32_t index, |
6935 Object* holder) { | 7063 Object* holder) { |
| 7064 Isolate* isolate = GetIsolate(); |
6936 ASSERT(!structure->IsProxy()); | 7065 ASSERT(!structure->IsProxy()); |
6937 | 7066 |
6938 // api style callbacks. | 7067 // api style callbacks. |
6939 if (structure->IsAccessorInfo()) { | 7068 if (structure->IsAccessorInfo()) { |
6940 AccessorInfo* data = AccessorInfo::cast(structure); | 7069 AccessorInfo* data = AccessorInfo::cast(structure); |
6941 Object* fun_obj = data->getter(); | 7070 Object* fun_obj = data->getter(); |
6942 v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj); | 7071 v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj); |
6943 HandleScope scope; | 7072 HandleScope scope(isolate); |
6944 Handle<JSObject> self(JSObject::cast(receiver)); | 7073 Handle<JSObject> self(JSObject::cast(receiver)); |
6945 Handle<JSObject> holder_handle(JSObject::cast(holder)); | 7074 Handle<JSObject> holder_handle(JSObject::cast(holder)); |
6946 Handle<Object> number = Factory::NewNumberFromUint(index); | 7075 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
6947 Handle<String> key(Factory::NumberToString(number)); | 7076 Handle<String> key(isolate->factory()->NumberToString(number)); |
6948 LOG(ApiNamedPropertyAccess("load", *self, *key)); | 7077 LOG(isolate, ApiNamedPropertyAccess("load", *self, *key)); |
6949 CustomArguments args(data->data(), *self, *holder_handle); | 7078 CustomArguments args(isolate, data->data(), *self, *holder_handle); |
6950 v8::AccessorInfo info(args.end()); | 7079 v8::AccessorInfo info(args.end()); |
6951 v8::Handle<v8::Value> result; | 7080 v8::Handle<v8::Value> result; |
6952 { | 7081 { |
6953 // Leaving JavaScript. | 7082 // Leaving JavaScript. |
6954 VMState state(EXTERNAL); | 7083 VMState state(isolate, EXTERNAL); |
6955 result = call_fun(v8::Utils::ToLocal(key), info); | 7084 result = call_fun(v8::Utils::ToLocal(key), info); |
6956 } | 7085 } |
6957 RETURN_IF_SCHEDULED_EXCEPTION(); | 7086 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
6958 if (result.IsEmpty()) return Heap::undefined_value(); | 7087 if (result.IsEmpty()) return isolate->heap()->undefined_value(); |
6959 return *v8::Utils::OpenHandle(*result); | 7088 return *v8::Utils::OpenHandle(*result); |
6960 } | 7089 } |
6961 | 7090 |
6962 // __defineGetter__ callback | 7091 // __defineGetter__ callback |
6963 if (structure->IsFixedArray()) { | 7092 if (structure->IsFixedArray()) { |
6964 Object* getter = FixedArray::cast(structure)->get(kGetterIndex); | 7093 Object* getter = FixedArray::cast(structure)->get(kGetterIndex); |
6965 if (getter->IsJSFunction()) { | 7094 if (getter->IsJSFunction()) { |
6966 return Object::GetPropertyWithDefinedGetter(receiver, | 7095 return Object::GetPropertyWithDefinedGetter(receiver, |
6967 JSFunction::cast(getter)); | 7096 JSFunction::cast(getter)); |
6968 } | 7097 } |
6969 // Getter is not a function. | 7098 // Getter is not a function. |
6970 return Heap::undefined_value(); | 7099 return isolate->heap()->undefined_value(); |
6971 } | 7100 } |
6972 | 7101 |
6973 UNREACHABLE(); | 7102 UNREACHABLE(); |
6974 return NULL; | 7103 return NULL; |
6975 } | 7104 } |
6976 | 7105 |
6977 | 7106 |
6978 MaybeObject* JSObject::SetElementWithCallback(Object* structure, | 7107 MaybeObject* JSObject::SetElementWithCallback(Object* structure, |
6979 uint32_t index, | 7108 uint32_t index, |
6980 Object* value, | 7109 Object* value, |
6981 JSObject* holder) { | 7110 JSObject* holder) { |
6982 HandleScope scope; | 7111 Isolate* isolate = GetIsolate(); |
| 7112 HandleScope scope(isolate); |
6983 | 7113 |
6984 // We should never get here to initialize a const with the hole | 7114 // We should never get here to initialize a const with the hole |
6985 // value since a const declaration would conflict with the setter. | 7115 // value since a const declaration would conflict with the setter. |
6986 ASSERT(!value->IsTheHole()); | 7116 ASSERT(!value->IsTheHole()); |
6987 Handle<Object> value_handle(value); | 7117 Handle<Object> value_handle(value, isolate); |
6988 | 7118 |
6989 // To accommodate both the old and the new api we switch on the | 7119 // To accommodate both the old and the new api we switch on the |
6990 // data structure used to store the callbacks. Eventually proxy | 7120 // data structure used to store the callbacks. Eventually proxy |
6991 // callbacks should be phased out. | 7121 // callbacks should be phased out. |
6992 ASSERT(!structure->IsProxy()); | 7122 ASSERT(!structure->IsProxy()); |
6993 | 7123 |
6994 if (structure->IsAccessorInfo()) { | 7124 if (structure->IsAccessorInfo()) { |
6995 // api style callbacks | 7125 // api style callbacks |
6996 AccessorInfo* data = AccessorInfo::cast(structure); | 7126 AccessorInfo* data = AccessorInfo::cast(structure); |
6997 Object* call_obj = data->setter(); | 7127 Object* call_obj = data->setter(); |
6998 v8::AccessorSetter call_fun = v8::ToCData<v8::AccessorSetter>(call_obj); | 7128 v8::AccessorSetter call_fun = v8::ToCData<v8::AccessorSetter>(call_obj); |
6999 if (call_fun == NULL) return value; | 7129 if (call_fun == NULL) return value; |
7000 Handle<Object> number = Factory::NewNumberFromUint(index); | 7130 Handle<Object> number = isolate->factory()->NewNumberFromUint(index); |
7001 Handle<String> key(Factory::NumberToString(number)); | 7131 Handle<String> key(isolate->factory()->NumberToString(number)); |
7002 LOG(ApiNamedPropertyAccess("store", this, *key)); | 7132 LOG(isolate, ApiNamedPropertyAccess("store", this, *key)); |
7003 CustomArguments args(data->data(), this, JSObject::cast(holder)); | 7133 CustomArguments args(isolate, data->data(), this, JSObject::cast(holder)); |
7004 v8::AccessorInfo info(args.end()); | 7134 v8::AccessorInfo info(args.end()); |
7005 { | 7135 { |
7006 // Leaving JavaScript. | 7136 // Leaving JavaScript. |
7007 VMState state(EXTERNAL); | 7137 VMState state(isolate, EXTERNAL); |
7008 call_fun(v8::Utils::ToLocal(key), | 7138 call_fun(v8::Utils::ToLocal(key), |
7009 v8::Utils::ToLocal(value_handle), | 7139 v8::Utils::ToLocal(value_handle), |
7010 info); | 7140 info); |
7011 } | 7141 } |
7012 RETURN_IF_SCHEDULED_EXCEPTION(); | 7142 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
7013 return *value_handle; | 7143 return *value_handle; |
7014 } | 7144 } |
7015 | 7145 |
7016 if (structure->IsFixedArray()) { | 7146 if (structure->IsFixedArray()) { |
7017 Object* setter = FixedArray::cast(structure)->get(kSetterIndex); | 7147 Object* setter = FixedArray::cast(structure)->get(kSetterIndex); |
7018 if (setter->IsJSFunction()) { | 7148 if (setter->IsJSFunction()) { |
7019 return SetPropertyWithDefinedSetter(JSFunction::cast(setter), value); | 7149 return SetPropertyWithDefinedSetter(JSFunction::cast(setter), value); |
7020 } else { | 7150 } else { |
7021 Handle<Object> holder_handle(holder); | 7151 Handle<Object> holder_handle(holder, isolate); |
7022 Handle<Object> key(Factory::NewNumberFromUint(index)); | 7152 Handle<Object> key(isolate->factory()->NewNumberFromUint(index)); |
7023 Handle<Object> args[2] = { key, holder_handle }; | 7153 Handle<Object> args[2] = { key, holder_handle }; |
7024 return Top::Throw(*Factory::NewTypeError("no_setter_in_callback", | 7154 return isolate->Throw( |
7025 HandleVector(args, 2))); | 7155 *isolate->factory()->NewTypeError("no_setter_in_callback", |
| 7156 HandleVector(args, 2))); |
7026 } | 7157 } |
7027 } | 7158 } |
7028 | 7159 |
7029 UNREACHABLE(); | 7160 UNREACHABLE(); |
7030 return NULL; | 7161 return NULL; |
7031 } | 7162 } |
7032 | 7163 |
7033 | 7164 |
7034 // Adding n elements in fast case is O(n*n). | 7165 // Adding n elements in fast case is O(n*n). |
7035 // Note: revisit design to have dual undefined values to capture absent | 7166 // Note: revisit design to have dual undefined values to capture absent |
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7094 } | 7225 } |
7095 ASSERT(HasDictionaryElements()); | 7226 ASSERT(HasDictionaryElements()); |
7096 return SetElement(index, value, strict_mode, check_prototype); | 7227 return SetElement(index, value, strict_mode, check_prototype); |
7097 } | 7228 } |
7098 | 7229 |
7099 | 7230 |
7100 MaybeObject* JSObject::SetElement(uint32_t index, | 7231 MaybeObject* JSObject::SetElement(uint32_t index, |
7101 Object* value, | 7232 Object* value, |
7102 StrictModeFlag strict_mode, | 7233 StrictModeFlag strict_mode, |
7103 bool check_prototype) { | 7234 bool check_prototype) { |
| 7235 Heap* heap = GetHeap(); |
7104 // Check access rights if needed. | 7236 // Check access rights if needed. |
7105 if (IsAccessCheckNeeded() && | 7237 if (IsAccessCheckNeeded() && |
7106 !Top::MayIndexedAccess(this, index, v8::ACCESS_SET)) { | 7238 !heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_SET)) { |
7107 HandleScope scope; | 7239 HandleScope scope; |
7108 Handle<Object> value_handle(value); | 7240 Handle<Object> value_handle(value); |
7109 Top::ReportFailedAccessCheck(this, v8::ACCESS_SET); | 7241 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET); |
7110 return *value_handle; | 7242 return *value_handle; |
7111 } | 7243 } |
7112 | 7244 |
7113 if (IsJSGlobalProxy()) { | 7245 if (IsJSGlobalProxy()) { |
7114 Object* proto = GetPrototype(); | 7246 Object* proto = GetPrototype(); |
7115 if (proto->IsNull()) return value; | 7247 if (proto->IsNull()) return value; |
7116 ASSERT(proto->IsJSGlobalObject()); | 7248 ASSERT(proto->IsJSGlobalObject()); |
7117 return JSObject::cast(proto)->SetElement(index, | 7249 return JSObject::cast(proto)->SetElement(index, |
7118 value, | 7250 value, |
7119 strict_mode, | 7251 strict_mode, |
(...skipping 12 matching lines...) Expand all Loading... |
7132 value, | 7264 value, |
7133 strict_mode, | 7265 strict_mode, |
7134 check_prototype); | 7266 check_prototype); |
7135 } | 7267 } |
7136 | 7268 |
7137 | 7269 |
7138 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, | 7270 MaybeObject* JSObject::SetElementWithoutInterceptor(uint32_t index, |
7139 Object* value, | 7271 Object* value, |
7140 StrictModeFlag strict_mode, | 7272 StrictModeFlag strict_mode, |
7141 bool check_prototype) { | 7273 bool check_prototype) { |
| 7274 Isolate* isolate = GetIsolate(); |
7142 switch (GetElementsKind()) { | 7275 switch (GetElementsKind()) { |
7143 case FAST_ELEMENTS: | 7276 case FAST_ELEMENTS: |
7144 // Fast case. | 7277 // Fast case. |
7145 return SetFastElement(index, value, strict_mode, check_prototype); | 7278 return SetFastElement(index, value, strict_mode, check_prototype); |
7146 case EXTERNAL_PIXEL_ELEMENTS: { | 7279 case EXTERNAL_PIXEL_ELEMENTS: { |
7147 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); | 7280 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); |
7148 return pixels->SetValue(index, value); | 7281 return pixels->SetValue(index, value); |
7149 } | 7282 } |
7150 case EXTERNAL_BYTE_ELEMENTS: { | 7283 case EXTERNAL_BYTE_ELEMENTS: { |
7151 ExternalByteArray* array = ExternalByteArray::cast(elements()); | 7284 ExternalByteArray* array = ExternalByteArray::cast(elements()); |
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7187 if (entry != NumberDictionary::kNotFound) { | 7320 if (entry != NumberDictionary::kNotFound) { |
7188 Object* element = dictionary->ValueAt(entry); | 7321 Object* element = dictionary->ValueAt(entry); |
7189 PropertyDetails details = dictionary->DetailsAt(entry); | 7322 PropertyDetails details = dictionary->DetailsAt(entry); |
7190 if (details.type() == CALLBACKS) { | 7323 if (details.type() == CALLBACKS) { |
7191 return SetElementWithCallback(element, index, value, this); | 7324 return SetElementWithCallback(element, index, value, this); |
7192 } else { | 7325 } else { |
7193 dictionary->UpdateMaxNumberKey(index); | 7326 dictionary->UpdateMaxNumberKey(index); |
7194 // If put fails instrict mode, throw exception. | 7327 // If put fails instrict mode, throw exception. |
7195 if (!dictionary->ValueAtPut(entry, value) && | 7328 if (!dictionary->ValueAtPut(entry, value) && |
7196 strict_mode == kStrictMode) { | 7329 strict_mode == kStrictMode) { |
7197 Handle<Object> number(Factory::NewNumberFromUint(index)); | 7330 Handle<Object> number(isolate->factory()->NewNumberFromUint(index)); |
7198 Handle<Object> holder(this); | 7331 Handle<Object> holder(this); |
7199 Handle<Object> args[2] = { number, holder }; | 7332 Handle<Object> args[2] = { number, holder }; |
7200 return Top::Throw( | 7333 return isolate->Throw( |
7201 *Factory::NewTypeError("strict_read_only_property", | 7334 *isolate->factory()->NewTypeError("strict_read_only_property", |
7202 HandleVector(args, 2))); | 7335 HandleVector(args, 2))); |
7203 } | 7336 } |
7204 } | 7337 } |
7205 } else { | 7338 } else { |
7206 // Index not already used. Look for an accessor in the prototype chain. | 7339 // Index not already used. Look for an accessor in the prototype chain. |
7207 if (check_prototype) { | 7340 if (check_prototype) { |
7208 bool found; | 7341 bool found; |
7209 MaybeObject* result = | 7342 MaybeObject* result = |
7210 // Strict mode not needed. No-setter case already handled. | 7343 // Strict mode not needed. No-setter case already handled. |
7211 SetElementWithCallbackSetterInPrototypes(index, value, &found); | 7344 SetElementWithCallbackSetterInPrototypes(index, value, &found); |
7212 if (found) return result; | 7345 if (found) return result; |
7213 } | 7346 } |
7214 // When we set the is_extensible flag to false we always force | 7347 // When we set the is_extensible flag to false we always force |
7215 // the element into dictionary mode (and force them to stay there). | 7348 // the element into dictionary mode (and force them to stay there). |
7216 if (!map()->is_extensible()) { | 7349 if (!map()->is_extensible()) { |
7217 Handle<Object> number(Factory::NewNumberFromUint(index)); | 7350 Handle<Object> number(isolate->factory()->NewNumberFromUint(index)); |
7218 Handle<String> index_string(Factory::NumberToString(number)); | 7351 Handle<String> index_string( |
| 7352 isolate->factory()->NumberToString(number)); |
7219 Handle<Object> args[1] = { index_string }; | 7353 Handle<Object> args[1] = { index_string }; |
7220 return Top::Throw(*Factory::NewTypeError("object_not_extensible", | 7354 return isolate->Throw( |
7221 HandleVector(args, 1))); | 7355 *isolate->factory()->NewTypeError("object_not_extensible", |
| 7356 HandleVector(args, 1))); |
7222 } | 7357 } |
7223 Object* result; | 7358 Object* result; |
7224 { MaybeObject* maybe_result = dictionary->AtNumberPut(index, value); | 7359 { MaybeObject* maybe_result = dictionary->AtNumberPut(index, value); |
7225 if (!maybe_result->ToObject(&result)) return maybe_result; | 7360 if (!maybe_result->ToObject(&result)) return maybe_result; |
7226 } | 7361 } |
7227 if (elms != FixedArray::cast(result)) { | 7362 if (elms != FixedArray::cast(result)) { |
7228 set_elements(FixedArray::cast(result)); | 7363 set_elements(FixedArray::cast(result)); |
7229 } | 7364 } |
7230 } | 7365 } |
7231 | 7366 |
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7264 | 7399 |
7265 return value; | 7400 return value; |
7266 } | 7401 } |
7267 default: | 7402 default: |
7268 UNREACHABLE(); | 7403 UNREACHABLE(); |
7269 break; | 7404 break; |
7270 } | 7405 } |
7271 // All possible cases have been handled above. Add a return to avoid the | 7406 // All possible cases have been handled above. Add a return to avoid the |
7272 // complaints from the compiler. | 7407 // complaints from the compiler. |
7273 UNREACHABLE(); | 7408 UNREACHABLE(); |
7274 return Heap::null_value(); | 7409 return isolate->heap()->null_value(); |
7275 } | 7410 } |
7276 | 7411 |
7277 | 7412 |
7278 MaybeObject* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index, | 7413 MaybeObject* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index, |
7279 Object* value) { | 7414 Object* value) { |
7280 uint32_t old_len = 0; | 7415 uint32_t old_len = 0; |
7281 CHECK(length()->ToArrayIndex(&old_len)); | 7416 CHECK(length()->ToArrayIndex(&old_len)); |
7282 // Check to see if we need to update the length. For now, we make | 7417 // Check to see if we need to update the length. For now, we make |
7283 // sure that the length stays within 32-bits (unsigned). | 7418 // sure that the length stays within 32-bits (unsigned). |
7284 if (index >= old_len && index != 0xffffffff) { | 7419 if (index >= old_len && index != 0xffffffff) { |
7285 Object* len; | 7420 Object* len; |
7286 { MaybeObject* maybe_len = | 7421 { MaybeObject* maybe_len = |
7287 Heap::NumberFromDouble(static_cast<double>(index) + 1); | 7422 GetHeap()->NumberFromDouble(static_cast<double>(index) + 1); |
7288 if (!maybe_len->ToObject(&len)) return maybe_len; | 7423 if (!maybe_len->ToObject(&len)) return maybe_len; |
7289 } | 7424 } |
7290 set_length(len); | 7425 set_length(len); |
7291 } | 7426 } |
7292 return value; | 7427 return value; |
7293 } | 7428 } |
7294 | 7429 |
7295 | 7430 |
7296 MaybeObject* JSObject::GetElementPostInterceptor(Object* receiver, | 7431 MaybeObject* JSObject::GetElementPostInterceptor(Object* receiver, |
7297 uint32_t index) { | 7432 uint32_t index) { |
| 7433 Heap* heap = GetHeap(); |
7298 // Get element works for both JSObject and JSArray since | 7434 // Get element works for both JSObject and JSArray since |
7299 // JSArray::length cannot change. | 7435 // JSArray::length cannot change. |
7300 switch (GetElementsKind()) { | 7436 switch (GetElementsKind()) { |
7301 case FAST_ELEMENTS: { | 7437 case FAST_ELEMENTS: { |
7302 FixedArray* elms = FixedArray::cast(elements()); | 7438 FixedArray* elms = FixedArray::cast(elements()); |
7303 if (index < static_cast<uint32_t>(elms->length())) { | 7439 if (index < static_cast<uint32_t>(elms->length())) { |
7304 Object* value = elms->get(index); | 7440 Object* value = elms->get(index); |
7305 if (!value->IsTheHole()) return value; | 7441 if (!value->IsTheHole()) return value; |
7306 } | 7442 } |
7307 break; | 7443 break; |
(...skipping 28 matching lines...) Expand all Loading... |
7336 } | 7472 } |
7337 break; | 7473 break; |
7338 } | 7474 } |
7339 default: | 7475 default: |
7340 UNREACHABLE(); | 7476 UNREACHABLE(); |
7341 break; | 7477 break; |
7342 } | 7478 } |
7343 | 7479 |
7344 // Continue searching via the prototype chain. | 7480 // Continue searching via the prototype chain. |
7345 Object* pt = GetPrototype(); | 7481 Object* pt = GetPrototype(); |
7346 if (pt == Heap::null_value()) return Heap::undefined_value(); | 7482 if (pt->IsNull()) return heap->undefined_value(); |
7347 return pt->GetElementWithReceiver(receiver, index); | 7483 return pt->GetElementWithReceiver(receiver, index); |
7348 } | 7484 } |
7349 | 7485 |
7350 | 7486 |
7351 MaybeObject* JSObject::GetElementWithInterceptor(Object* receiver, | 7487 MaybeObject* JSObject::GetElementWithInterceptor(Object* receiver, |
7352 uint32_t index) { | 7488 uint32_t index) { |
| 7489 Isolate* isolate = GetIsolate(); |
7353 // Make sure that the top context does not change when doing | 7490 // Make sure that the top context does not change when doing |
7354 // callbacks or interceptor calls. | 7491 // callbacks or interceptor calls. |
7355 AssertNoContextChange ncc; | 7492 AssertNoContextChange ncc; |
7356 HandleScope scope; | 7493 HandleScope scope(isolate); |
7357 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); | 7494 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); |
7358 Handle<Object> this_handle(receiver); | 7495 Handle<Object> this_handle(receiver); |
7359 Handle<JSObject> holder_handle(this); | 7496 Handle<JSObject> holder_handle(this); |
7360 | 7497 |
7361 if (!interceptor->getter()->IsUndefined()) { | 7498 if (!interceptor->getter()->IsUndefined()) { |
7362 v8::IndexedPropertyGetter getter = | 7499 v8::IndexedPropertyGetter getter = |
7363 v8::ToCData<v8::IndexedPropertyGetter>(interceptor->getter()); | 7500 v8::ToCData<v8::IndexedPropertyGetter>(interceptor->getter()); |
7364 LOG(ApiIndexedPropertyAccess("interceptor-indexed-get", this, index)); | 7501 LOG(isolate, |
7365 CustomArguments args(interceptor->data(), receiver, this); | 7502 ApiIndexedPropertyAccess("interceptor-indexed-get", this, index)); |
| 7503 CustomArguments args(isolate, interceptor->data(), receiver, this); |
7366 v8::AccessorInfo info(args.end()); | 7504 v8::AccessorInfo info(args.end()); |
7367 v8::Handle<v8::Value> result; | 7505 v8::Handle<v8::Value> result; |
7368 { | 7506 { |
7369 // Leaving JavaScript. | 7507 // Leaving JavaScript. |
7370 VMState state(EXTERNAL); | 7508 VMState state(isolate, EXTERNAL); |
7371 result = getter(index, info); | 7509 result = getter(index, info); |
7372 } | 7510 } |
7373 RETURN_IF_SCHEDULED_EXCEPTION(); | 7511 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
7374 if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result); | 7512 if (!result.IsEmpty()) return *v8::Utils::OpenHandle(*result); |
7375 } | 7513 } |
7376 | 7514 |
7377 MaybeObject* raw_result = | 7515 MaybeObject* raw_result = |
7378 holder_handle->GetElementPostInterceptor(*this_handle, index); | 7516 holder_handle->GetElementPostInterceptor(*this_handle, index); |
7379 RETURN_IF_SCHEDULED_EXCEPTION(); | 7517 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
7380 return raw_result; | 7518 return raw_result; |
7381 } | 7519 } |
7382 | 7520 |
7383 | 7521 |
7384 MaybeObject* JSObject::GetElementWithReceiver(Object* receiver, | 7522 MaybeObject* JSObject::GetElementWithReceiver(Object* receiver, |
7385 uint32_t index) { | 7523 uint32_t index) { |
| 7524 Heap* heap = GetHeap(); |
7386 // Check access rights if needed. | 7525 // Check access rights if needed. |
7387 if (IsAccessCheckNeeded() && | 7526 if (IsAccessCheckNeeded() && |
7388 !Top::MayIndexedAccess(this, index, v8::ACCESS_GET)) { | 7527 !heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_GET)) { |
7389 Top::ReportFailedAccessCheck(this, v8::ACCESS_GET); | 7528 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_GET); |
7390 return Heap::undefined_value(); | 7529 return heap->undefined_value(); |
7391 } | 7530 } |
7392 | 7531 |
7393 if (HasIndexedInterceptor()) { | 7532 if (HasIndexedInterceptor()) { |
7394 return GetElementWithInterceptor(receiver, index); | 7533 return GetElementWithInterceptor(receiver, index); |
7395 } | 7534 } |
7396 | 7535 |
7397 // Get element works for both JSObject and JSArray since | 7536 // Get element works for both JSObject and JSArray since |
7398 // JSArray::length cannot change. | 7537 // JSArray::length cannot change. |
7399 switch (GetElementsKind()) { | 7538 switch (GetElementsKind()) { |
7400 case FAST_ELEMENTS: { | 7539 case FAST_ELEMENTS: { |
(...skipping 30 matching lines...) Expand all Loading... |
7431 index, | 7570 index, |
7432 this); | 7571 this); |
7433 } | 7572 } |
7434 return element; | 7573 return element; |
7435 } | 7574 } |
7436 break; | 7575 break; |
7437 } | 7576 } |
7438 } | 7577 } |
7439 | 7578 |
7440 Object* pt = GetPrototype(); | 7579 Object* pt = GetPrototype(); |
7441 if (pt == Heap::null_value()) return Heap::undefined_value(); | 7580 if (pt == heap->null_value()) return heap->undefined_value(); |
7442 return pt->GetElementWithReceiver(receiver, index); | 7581 return pt->GetElementWithReceiver(receiver, index); |
7443 } | 7582 } |
7444 | 7583 |
7445 | 7584 |
7446 MaybeObject* JSObject::GetExternalElement(uint32_t index) { | 7585 MaybeObject* JSObject::GetExternalElement(uint32_t index) { |
7447 // Get element works for both JSObject and JSArray since | 7586 // Get element works for both JSObject and JSArray since |
7448 // JSArray::length cannot change. | 7587 // JSArray::length cannot change. |
7449 switch (GetElementsKind()) { | 7588 switch (GetElementsKind()) { |
7450 case EXTERNAL_PIXEL_ELEMENTS: { | 7589 case EXTERNAL_PIXEL_ELEMENTS: { |
7451 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); | 7590 ExternalPixelArray* pixels = ExternalPixelArray::cast(elements()); |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7486 if (index < static_cast<uint32_t>(array->length())) { | 7625 if (index < static_cast<uint32_t>(array->length())) { |
7487 uint16_t value = array->get(index); | 7626 uint16_t value = array->get(index); |
7488 return Smi::FromInt(value); | 7627 return Smi::FromInt(value); |
7489 } | 7628 } |
7490 break; | 7629 break; |
7491 } | 7630 } |
7492 case EXTERNAL_INT_ELEMENTS: { | 7631 case EXTERNAL_INT_ELEMENTS: { |
7493 ExternalIntArray* array = ExternalIntArray::cast(elements()); | 7632 ExternalIntArray* array = ExternalIntArray::cast(elements()); |
7494 if (index < static_cast<uint32_t>(array->length())) { | 7633 if (index < static_cast<uint32_t>(array->length())) { |
7495 int32_t value = array->get(index); | 7634 int32_t value = array->get(index); |
7496 return Heap::NumberFromInt32(value); | 7635 return GetHeap()->NumberFromInt32(value); |
7497 } | 7636 } |
7498 break; | 7637 break; |
7499 } | 7638 } |
7500 case EXTERNAL_UNSIGNED_INT_ELEMENTS: { | 7639 case EXTERNAL_UNSIGNED_INT_ELEMENTS: { |
7501 ExternalUnsignedIntArray* array = | 7640 ExternalUnsignedIntArray* array = |
7502 ExternalUnsignedIntArray::cast(elements()); | 7641 ExternalUnsignedIntArray::cast(elements()); |
7503 if (index < static_cast<uint32_t>(array->length())) { | 7642 if (index < static_cast<uint32_t>(array->length())) { |
7504 uint32_t value = array->get(index); | 7643 uint32_t value = array->get(index); |
7505 return Heap::NumberFromUint32(value); | 7644 return GetHeap()->NumberFromUint32(value); |
7506 } | 7645 } |
7507 break; | 7646 break; |
7508 } | 7647 } |
7509 case EXTERNAL_FLOAT_ELEMENTS: { | 7648 case EXTERNAL_FLOAT_ELEMENTS: { |
7510 ExternalFloatArray* array = ExternalFloatArray::cast(elements()); | 7649 ExternalFloatArray* array = ExternalFloatArray::cast(elements()); |
7511 if (index < static_cast<uint32_t>(array->length())) { | 7650 if (index < static_cast<uint32_t>(array->length())) { |
7512 float value = array->get(index); | 7651 float value = array->get(index); |
7513 return Heap::AllocateHeapNumber(value); | 7652 return GetHeap()->AllocateHeapNumber(value); |
7514 } | 7653 } |
7515 break; | 7654 break; |
7516 } | 7655 } |
7517 case FAST_ELEMENTS: | 7656 case FAST_ELEMENTS: |
7518 case DICTIONARY_ELEMENTS: | 7657 case DICTIONARY_ELEMENTS: |
7519 UNREACHABLE(); | 7658 UNREACHABLE(); |
7520 break; | 7659 break; |
7521 } | 7660 } |
7522 return Heap::undefined_value(); | 7661 return GetHeap()->undefined_value(); |
7523 } | 7662 } |
7524 | 7663 |
7525 | 7664 |
7526 bool JSObject::HasDenseElements() { | 7665 bool JSObject::HasDenseElements() { |
7527 int capacity = 0; | 7666 int capacity = 0; |
7528 int number_of_elements = 0; | 7667 int number_of_elements = 0; |
7529 | 7668 |
7530 switch (GetElementsKind()) { | 7669 switch (GetElementsKind()) { |
7531 case FAST_ELEMENTS: { | 7670 case FAST_ELEMENTS: { |
7532 FixedArray* elms = FixedArray::cast(elements()); | 7671 FixedArray* elms = FixedArray::cast(elements()); |
(...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
7657 Object* result = | 7796 Object* result = |
7658 constructor->shared()->get_api_func_data()->indexed_property_handler(); | 7797 constructor->shared()->get_api_func_data()->indexed_property_handler(); |
7659 return InterceptorInfo::cast(result); | 7798 return InterceptorInfo::cast(result); |
7660 } | 7799 } |
7661 | 7800 |
7662 | 7801 |
7663 MaybeObject* JSObject::GetPropertyPostInterceptor( | 7802 MaybeObject* JSObject::GetPropertyPostInterceptor( |
7664 JSObject* receiver, | 7803 JSObject* receiver, |
7665 String* name, | 7804 String* name, |
7666 PropertyAttributes* attributes) { | 7805 PropertyAttributes* attributes) { |
| 7806 Heap* heap = GetHeap(); |
7667 // Check local property in holder, ignore interceptor. | 7807 // Check local property in holder, ignore interceptor. |
7668 LookupResult result; | 7808 LookupResult result; |
7669 LocalLookupRealNamedProperty(name, &result); | 7809 LocalLookupRealNamedProperty(name, &result); |
7670 if (result.IsProperty()) { | 7810 if (result.IsProperty()) { |
7671 return GetProperty(receiver, &result, name, attributes); | 7811 return GetProperty(receiver, &result, name, attributes); |
7672 } | 7812 } |
7673 // Continue searching via the prototype chain. | 7813 // Continue searching via the prototype chain. |
7674 Object* pt = GetPrototype(); | 7814 Object* pt = GetPrototype(); |
7675 *attributes = ABSENT; | 7815 *attributes = ABSENT; |
7676 if (pt == Heap::null_value()) return Heap::undefined_value(); | 7816 if (pt->IsNull()) return heap->undefined_value(); |
7677 return pt->GetPropertyWithReceiver(receiver, name, attributes); | 7817 return pt->GetPropertyWithReceiver(receiver, name, attributes); |
7678 } | 7818 } |
7679 | 7819 |
7680 | 7820 |
7681 MaybeObject* JSObject::GetLocalPropertyPostInterceptor( | 7821 MaybeObject* JSObject::GetLocalPropertyPostInterceptor( |
7682 JSObject* receiver, | 7822 JSObject* receiver, |
7683 String* name, | 7823 String* name, |
7684 PropertyAttributes* attributes) { | 7824 PropertyAttributes* attributes) { |
| 7825 Heap* heap = GetHeap(); |
7685 // Check local property in holder, ignore interceptor. | 7826 // Check local property in holder, ignore interceptor. |
7686 LookupResult result; | 7827 LookupResult result; |
7687 LocalLookupRealNamedProperty(name, &result); | 7828 LocalLookupRealNamedProperty(name, &result); |
7688 if (result.IsProperty()) { | 7829 if (result.IsProperty()) { |
7689 return GetProperty(receiver, &result, name, attributes); | 7830 return GetProperty(receiver, &result, name, attributes); |
7690 } | 7831 } |
7691 return Heap::undefined_value(); | 7832 return heap->undefined_value(); |
7692 } | 7833 } |
7693 | 7834 |
7694 | 7835 |
7695 MaybeObject* JSObject::GetPropertyWithInterceptor( | 7836 MaybeObject* JSObject::GetPropertyWithInterceptor( |
7696 JSObject* receiver, | 7837 JSObject* receiver, |
7697 String* name, | 7838 String* name, |
7698 PropertyAttributes* attributes) { | 7839 PropertyAttributes* attributes) { |
| 7840 Isolate* isolate = GetIsolate(); |
7699 InterceptorInfo* interceptor = GetNamedInterceptor(); | 7841 InterceptorInfo* interceptor = GetNamedInterceptor(); |
7700 HandleScope scope; | 7842 HandleScope scope(isolate); |
7701 Handle<JSObject> receiver_handle(receiver); | 7843 Handle<JSObject> receiver_handle(receiver); |
7702 Handle<JSObject> holder_handle(this); | 7844 Handle<JSObject> holder_handle(this); |
7703 Handle<String> name_handle(name); | 7845 Handle<String> name_handle(name); |
7704 | 7846 |
7705 if (!interceptor->getter()->IsUndefined()) { | 7847 if (!interceptor->getter()->IsUndefined()) { |
7706 v8::NamedPropertyGetter getter = | 7848 v8::NamedPropertyGetter getter = |
7707 v8::ToCData<v8::NamedPropertyGetter>(interceptor->getter()); | 7849 v8::ToCData<v8::NamedPropertyGetter>(interceptor->getter()); |
7708 LOG(ApiNamedPropertyAccess("interceptor-named-get", *holder_handle, name)); | 7850 LOG(isolate, |
7709 CustomArguments args(interceptor->data(), receiver, this); | 7851 ApiNamedPropertyAccess("interceptor-named-get", *holder_handle, name)); |
| 7852 CustomArguments args(isolate, interceptor->data(), receiver, this); |
7710 v8::AccessorInfo info(args.end()); | 7853 v8::AccessorInfo info(args.end()); |
7711 v8::Handle<v8::Value> result; | 7854 v8::Handle<v8::Value> result; |
7712 { | 7855 { |
7713 // Leaving JavaScript. | 7856 // Leaving JavaScript. |
7714 VMState state(EXTERNAL); | 7857 VMState state(isolate, EXTERNAL); |
7715 result = getter(v8::Utils::ToLocal(name_handle), info); | 7858 result = getter(v8::Utils::ToLocal(name_handle), info); |
7716 } | 7859 } |
7717 RETURN_IF_SCHEDULED_EXCEPTION(); | 7860 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
7718 if (!result.IsEmpty()) { | 7861 if (!result.IsEmpty()) { |
7719 *attributes = NONE; | 7862 *attributes = NONE; |
7720 return *v8::Utils::OpenHandle(*result); | 7863 return *v8::Utils::OpenHandle(*result); |
7721 } | 7864 } |
7722 } | 7865 } |
7723 | 7866 |
7724 MaybeObject* result = holder_handle->GetPropertyPostInterceptor( | 7867 MaybeObject* result = holder_handle->GetPropertyPostInterceptor( |
7725 *receiver_handle, | 7868 *receiver_handle, |
7726 *name_handle, | 7869 *name_handle, |
7727 attributes); | 7870 attributes); |
7728 RETURN_IF_SCHEDULED_EXCEPTION(); | 7871 RETURN_IF_SCHEDULED_EXCEPTION(isolate); |
7729 return result; | 7872 return result; |
7730 } | 7873 } |
7731 | 7874 |
7732 | 7875 |
7733 bool JSObject::HasRealNamedProperty(String* key) { | 7876 bool JSObject::HasRealNamedProperty(String* key) { |
| 7877 Heap* heap = GetHeap(); |
7734 // Check access rights if needed. | 7878 // Check access rights if needed. |
7735 if (IsAccessCheckNeeded() && | 7879 if (IsAccessCheckNeeded() && |
7736 !Top::MayNamedAccess(this, key, v8::ACCESS_HAS)) { | 7880 !heap->isolate()->MayNamedAccess(this, key, v8::ACCESS_HAS)) { |
7737 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 7881 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
7738 return false; | 7882 return false; |
7739 } | 7883 } |
7740 | 7884 |
7741 LookupResult result; | 7885 LookupResult result; |
7742 LocalLookupRealNamedProperty(key, &result); | 7886 LocalLookupRealNamedProperty(key, &result); |
7743 return result.IsProperty() && (result.type() != INTERCEPTOR); | 7887 return result.IsProperty() && (result.type() != INTERCEPTOR); |
7744 } | 7888 } |
7745 | 7889 |
7746 | 7890 |
7747 bool JSObject::HasRealElementProperty(uint32_t index) { | 7891 bool JSObject::HasRealElementProperty(uint32_t index) { |
| 7892 Heap* heap = GetHeap(); |
7748 // Check access rights if needed. | 7893 // Check access rights if needed. |
7749 if (IsAccessCheckNeeded() && | 7894 if (IsAccessCheckNeeded() && |
7750 !Top::MayIndexedAccess(this, index, v8::ACCESS_HAS)) { | 7895 !heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { |
7751 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 7896 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
7752 return false; | 7897 return false; |
7753 } | 7898 } |
7754 | 7899 |
7755 // Handle [] on String objects. | 7900 // Handle [] on String objects. |
7756 if (this->IsStringObjectWithCharacterAt(index)) return true; | 7901 if (this->IsStringObjectWithCharacterAt(index)) return true; |
7757 | 7902 |
7758 switch (GetElementsKind()) { | 7903 switch (GetElementsKind()) { |
7759 case FAST_ELEMENTS: { | 7904 case FAST_ELEMENTS: { |
7760 uint32_t length = IsJSArray() ? | 7905 uint32_t length = IsJSArray() ? |
7761 static_cast<uint32_t>( | 7906 static_cast<uint32_t>( |
(...skipping 19 matching lines...) Expand all Loading... |
7781 case DICTIONARY_ELEMENTS: { | 7926 case DICTIONARY_ELEMENTS: { |
7782 return element_dictionary()->FindEntry(index) | 7927 return element_dictionary()->FindEntry(index) |
7783 != NumberDictionary::kNotFound; | 7928 != NumberDictionary::kNotFound; |
7784 } | 7929 } |
7785 default: | 7930 default: |
7786 UNREACHABLE(); | 7931 UNREACHABLE(); |
7787 break; | 7932 break; |
7788 } | 7933 } |
7789 // All possibilities have been handled above already. | 7934 // All possibilities have been handled above already. |
7790 UNREACHABLE(); | 7935 UNREACHABLE(); |
7791 return Heap::null_value(); | 7936 return heap->null_value(); |
7792 } | 7937 } |
7793 | 7938 |
7794 | 7939 |
7795 bool JSObject::HasRealNamedCallbackProperty(String* key) { | 7940 bool JSObject::HasRealNamedCallbackProperty(String* key) { |
| 7941 Heap* heap = GetHeap(); |
7796 // Check access rights if needed. | 7942 // Check access rights if needed. |
7797 if (IsAccessCheckNeeded() && | 7943 if (IsAccessCheckNeeded() && |
7798 !Top::MayNamedAccess(this, key, v8::ACCESS_HAS)) { | 7944 !heap->isolate()->MayNamedAccess(this, key, v8::ACCESS_HAS)) { |
7799 Top::ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 7945 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
7800 return false; | 7946 return false; |
7801 } | 7947 } |
7802 | 7948 |
7803 LookupResult result; | 7949 LookupResult result; |
7804 LocalLookupRealNamedProperty(key, &result); | 7950 LocalLookupRealNamedProperty(key, &result); |
7805 return result.IsProperty() && (result.type() == CALLBACKS); | 7951 return result.IsProperty() && (result.type() == CALLBACKS); |
7806 } | 7952 } |
7807 | 7953 |
7808 | 7954 |
7809 int JSObject::NumberOfLocalProperties(PropertyAttributes filter) { | 7955 int JSObject::NumberOfLocalProperties(PropertyAttributes filter) { |
(...skipping 242 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8052 return counter; | 8198 return counter; |
8053 } | 8199 } |
8054 | 8200 |
8055 | 8201 |
8056 int JSObject::GetEnumElementKeys(FixedArray* storage) { | 8202 int JSObject::GetEnumElementKeys(FixedArray* storage) { |
8057 return GetLocalElementKeys(storage, | 8203 return GetLocalElementKeys(storage, |
8058 static_cast<PropertyAttributes>(DONT_ENUM)); | 8204 static_cast<PropertyAttributes>(DONT_ENUM)); |
8059 } | 8205 } |
8060 | 8206 |
8061 | 8207 |
8062 bool NumberDictionaryShape::IsMatch(uint32_t key, Object* other) { | |
8063 ASSERT(other->IsNumber()); | |
8064 return key == static_cast<uint32_t>(other->Number()); | |
8065 } | |
8066 | |
8067 | |
8068 uint32_t NumberDictionaryShape::Hash(uint32_t key) { | |
8069 return ComputeIntegerHash(key); | |
8070 } | |
8071 | |
8072 | |
8073 uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) { | |
8074 ASSERT(other->IsNumber()); | |
8075 return ComputeIntegerHash(static_cast<uint32_t>(other->Number())); | |
8076 } | |
8077 | |
8078 | |
8079 MaybeObject* NumberDictionaryShape::AsObject(uint32_t key) { | |
8080 return Heap::NumberFromUint32(key); | |
8081 } | |
8082 | |
8083 | |
8084 bool StringDictionaryShape::IsMatch(String* key, Object* other) { | |
8085 // We know that all entries in a hash table had their hash keys created. | |
8086 // Use that knowledge to have fast failure. | |
8087 if (key->Hash() != String::cast(other)->Hash()) return false; | |
8088 return key->Equals(String::cast(other)); | |
8089 } | |
8090 | |
8091 | |
8092 uint32_t StringDictionaryShape::Hash(String* key) { | |
8093 return key->Hash(); | |
8094 } | |
8095 | |
8096 | |
8097 uint32_t StringDictionaryShape::HashForObject(String* key, Object* other) { | |
8098 return String::cast(other)->Hash(); | |
8099 } | |
8100 | |
8101 | |
8102 MaybeObject* StringDictionaryShape::AsObject(String* key) { | |
8103 return key; | |
8104 } | |
8105 | |
8106 | |
8107 // StringKey simply carries a string object as key. | 8208 // StringKey simply carries a string object as key. |
8108 class StringKey : public HashTableKey { | 8209 class StringKey : public HashTableKey { |
8109 public: | 8210 public: |
8110 explicit StringKey(String* string) : | 8211 explicit StringKey(String* string) : |
8111 string_(string), | 8212 string_(string), |
8112 hash_(HashForObject(string)) { } | 8213 hash_(HashForObject(string)) { } |
8113 | 8214 |
8114 bool IsMatch(Object* string) { | 8215 bool IsMatch(Object* string) { |
8115 // We know that all entries in a hash table had their hash keys created. | 8216 // We know that all entries in a hash table had their hash keys created. |
8116 // Use that knowledge to have fast failure. | 8217 // Use that knowledge to have fast failure. |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8179 FixedArray* pair = FixedArray::cast(obj); | 8280 FixedArray* pair = FixedArray::cast(obj); |
8180 SharedFunctionInfo* shared = SharedFunctionInfo::cast(pair->get(0)); | 8281 SharedFunctionInfo* shared = SharedFunctionInfo::cast(pair->get(0)); |
8181 String* source = String::cast(pair->get(1)); | 8282 String* source = String::cast(pair->get(1)); |
8182 StrictModeFlag strict_mode = static_cast<StrictModeFlag>( | 8283 StrictModeFlag strict_mode = static_cast<StrictModeFlag>( |
8183 Smi::cast(pair->get(2))->value()); | 8284 Smi::cast(pair->get(2))->value()); |
8184 return StringSharedHashHelper(source, shared, strict_mode); | 8285 return StringSharedHashHelper(source, shared, strict_mode); |
8185 } | 8286 } |
8186 | 8287 |
8187 MUST_USE_RESULT MaybeObject* AsObject() { | 8288 MUST_USE_RESULT MaybeObject* AsObject() { |
8188 Object* obj; | 8289 Object* obj; |
8189 { MaybeObject* maybe_obj = Heap::AllocateFixedArray(3); | 8290 { MaybeObject* maybe_obj = source_->GetHeap()->AllocateFixedArray(3); |
8190 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 8291 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
8191 } | 8292 } |
8192 FixedArray* pair = FixedArray::cast(obj); | 8293 FixedArray* pair = FixedArray::cast(obj); |
8193 pair->set(0, shared_); | 8294 pair->set(0, shared_); |
8194 pair->set(1, source_); | 8295 pair->set(1, source_); |
8195 pair->set(2, Smi::FromInt(strict_mode_)); | 8296 pair->set(2, Smi::FromInt(strict_mode_)); |
8196 return pair; | 8297 return pair; |
8197 } | 8298 } |
8198 | 8299 |
8199 private: | 8300 private: |
(...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8263 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. | 8364 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. |
8264 return result; | 8365 return result; |
8265 } | 8366 } |
8266 | 8367 |
8267 uint32_t HashForObject(Object* other) { | 8368 uint32_t HashForObject(Object* other) { |
8268 return String::cast(other)->Hash(); | 8369 return String::cast(other)->Hash(); |
8269 } | 8370 } |
8270 | 8371 |
8271 MaybeObject* AsObject() { | 8372 MaybeObject* AsObject() { |
8272 if (hash_field_ == 0) Hash(); | 8373 if (hash_field_ == 0) Hash(); |
8273 return Heap::AllocateSymbol(string_, chars_, hash_field_); | 8374 return Isolate::Current()->heap()->AllocateSymbol( |
| 8375 string_, chars_, hash_field_); |
8274 } | 8376 } |
8275 | 8377 |
8276 Vector<const char> string_; | 8378 Vector<const char> string_; |
8277 uint32_t hash_field_; | 8379 uint32_t hash_field_; |
8278 int chars_; // Caches the number of characters when computing the hash code. | 8380 int chars_; // Caches the number of characters when computing the hash code. |
8279 }; | 8381 }; |
8280 | 8382 |
8281 | 8383 |
8282 template <typename Char> | 8384 template <typename Char> |
8283 class SequentialSymbolKey : public HashTableKey { | 8385 class SequentialSymbolKey : public HashTableKey { |
(...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8330 public: | 8432 public: |
8331 explicit AsciiSymbolKey(Vector<const char> str) | 8433 explicit AsciiSymbolKey(Vector<const char> str) |
8332 : SequentialSymbolKey<char>(str) { } | 8434 : SequentialSymbolKey<char>(str) { } |
8333 | 8435 |
8334 bool IsMatch(Object* string) { | 8436 bool IsMatch(Object* string) { |
8335 return String::cast(string)->IsAsciiEqualTo(string_); | 8437 return String::cast(string)->IsAsciiEqualTo(string_); |
8336 } | 8438 } |
8337 | 8439 |
8338 MaybeObject* AsObject() { | 8440 MaybeObject* AsObject() { |
8339 if (hash_field_ == 0) Hash(); | 8441 if (hash_field_ == 0) Hash(); |
8340 return Heap::AllocateAsciiSymbol(string_, hash_field_); | 8442 return HEAP->AllocateAsciiSymbol(string_, hash_field_); |
8341 } | 8443 } |
8342 }; | 8444 }; |
8343 | 8445 |
8344 | 8446 |
8345 class TwoByteSymbolKey : public SequentialSymbolKey<uc16> { | 8447 class TwoByteSymbolKey : public SequentialSymbolKey<uc16> { |
8346 public: | 8448 public: |
8347 explicit TwoByteSymbolKey(Vector<const uc16> str) | 8449 explicit TwoByteSymbolKey(Vector<const uc16> str) |
8348 : SequentialSymbolKey<uc16>(str) { } | 8450 : SequentialSymbolKey<uc16>(str) { } |
8349 | 8451 |
8350 bool IsMatch(Object* string) { | 8452 bool IsMatch(Object* string) { |
8351 return String::cast(string)->IsTwoByteEqualTo(string_); | 8453 return String::cast(string)->IsTwoByteEqualTo(string_); |
8352 } | 8454 } |
8353 | 8455 |
8354 MaybeObject* AsObject() { | 8456 MaybeObject* AsObject() { |
8355 if (hash_field_ == 0) Hash(); | 8457 if (hash_field_ == 0) Hash(); |
8356 return Heap::AllocateTwoByteSymbol(string_, hash_field_); | 8458 return HEAP->AllocateTwoByteSymbol(string_, hash_field_); |
8357 } | 8459 } |
8358 }; | 8460 }; |
8359 | 8461 |
8360 | 8462 |
8361 // SymbolKey carries a string/symbol object as key. | 8463 // SymbolKey carries a string/symbol object as key. |
8362 class SymbolKey : public HashTableKey { | 8464 class SymbolKey : public HashTableKey { |
8363 public: | 8465 public: |
8364 explicit SymbolKey(String* string) : string_(string) { } | 8466 explicit SymbolKey(String* string) |
| 8467 : string_(string) { } |
8365 | 8468 |
8366 bool IsMatch(Object* string) { | 8469 bool IsMatch(Object* string) { |
8367 return String::cast(string)->Equals(string_); | 8470 return String::cast(string)->Equals(string_); |
8368 } | 8471 } |
8369 | 8472 |
8370 uint32_t Hash() { return string_->Hash(); } | 8473 uint32_t Hash() { return string_->Hash(); } |
8371 | 8474 |
8372 uint32_t HashForObject(Object* other) { | 8475 uint32_t HashForObject(Object* other) { |
8373 return String::cast(other)->Hash(); | 8476 return String::cast(other)->Hash(); |
8374 } | 8477 } |
8375 | 8478 |
8376 MaybeObject* AsObject() { | 8479 MaybeObject* AsObject() { |
8377 // Attempt to flatten the string, so that symbols will most often | 8480 // Attempt to flatten the string, so that symbols will most often |
8378 // be flat strings. | 8481 // be flat strings. |
8379 string_ = string_->TryFlattenGetString(); | 8482 string_ = string_->TryFlattenGetString(); |
| 8483 Heap* heap = string_->GetHeap(); |
8380 // Transform string to symbol if possible. | 8484 // Transform string to symbol if possible. |
8381 Map* map = Heap::SymbolMapForString(string_); | 8485 Map* map = heap->SymbolMapForString(string_); |
8382 if (map != NULL) { | 8486 if (map != NULL) { |
8383 string_->set_map(map); | 8487 string_->set_map(map); |
8384 ASSERT(string_->IsSymbol()); | 8488 ASSERT(string_->IsSymbol()); |
8385 return string_; | 8489 return string_; |
8386 } | 8490 } |
8387 // Otherwise allocate a new symbol. | 8491 // Otherwise allocate a new symbol. |
8388 StringInputBuffer buffer(string_); | 8492 StringInputBuffer buffer(string_); |
8389 return Heap::AllocateInternalSymbol(&buffer, | 8493 return heap->AllocateInternalSymbol(&buffer, |
8390 string_->length(), | 8494 string_->length(), |
8391 string_->hash_field()); | 8495 string_->hash_field()); |
8392 } | 8496 } |
8393 | 8497 |
8394 static uint32_t StringHash(Object* obj) { | 8498 static uint32_t StringHash(Object* obj) { |
8395 return String::cast(obj)->Hash(); | 8499 return String::cast(obj)->Hash(); |
8396 } | 8500 } |
8397 | 8501 |
8398 String* string_; | 8502 String* string_; |
8399 }; | 8503 }; |
(...skipping 18 matching lines...) Expand all Loading... |
8418 PretenureFlag pretenure) { | 8522 PretenureFlag pretenure) { |
8419 const int kMinCapacity = 32; | 8523 const int kMinCapacity = 32; |
8420 int capacity = RoundUpToPowerOf2(at_least_space_for * 2); | 8524 int capacity = RoundUpToPowerOf2(at_least_space_for * 2); |
8421 if (capacity < kMinCapacity) { | 8525 if (capacity < kMinCapacity) { |
8422 capacity = kMinCapacity; // Guarantee min capacity. | 8526 capacity = kMinCapacity; // Guarantee min capacity. |
8423 } else if (capacity > HashTable::kMaxCapacity) { | 8527 } else if (capacity > HashTable::kMaxCapacity) { |
8424 return Failure::OutOfMemoryException(); | 8528 return Failure::OutOfMemoryException(); |
8425 } | 8529 } |
8426 | 8530 |
8427 Object* obj; | 8531 Object* obj; |
8428 { MaybeObject* maybe_obj = | 8532 { MaybeObject* maybe_obj = Isolate::Current()->heap()-> |
8429 Heap::AllocateHashTable(EntryToIndex(capacity), pretenure); | 8533 AllocateHashTable(EntryToIndex(capacity), pretenure); |
8430 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 8534 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
8431 } | 8535 } |
8432 HashTable::cast(obj)->SetNumberOfElements(0); | 8536 HashTable::cast(obj)->SetNumberOfElements(0); |
8433 HashTable::cast(obj)->SetNumberOfDeletedElements(0); | 8537 HashTable::cast(obj)->SetNumberOfDeletedElements(0); |
8434 HashTable::cast(obj)->SetCapacity(capacity); | 8538 HashTable::cast(obj)->SetCapacity(capacity); |
8435 return obj; | 8539 return obj; |
8436 } | 8540 } |
8437 | 8541 |
8438 | 8542 |
8439 // Find entry for key otherwise return kNotFound. | 8543 // Find entry for key otherwise return kNotFound. |
8440 template<typename Shape, typename Key> | |
8441 int HashTable<Shape, Key>::FindEntry(Key key) { | |
8442 uint32_t capacity = Capacity(); | |
8443 uint32_t entry = FirstProbe(Shape::Hash(key), capacity); | |
8444 uint32_t count = 1; | |
8445 // EnsureCapacity will guarantee the hash table is never full. | |
8446 while (true) { | |
8447 Object* element = KeyAt(entry); | |
8448 if (element->IsUndefined()) break; // Empty entry. | |
8449 if (!element->IsNull() && Shape::IsMatch(key, element)) return entry; | |
8450 entry = NextProbe(entry, count++, capacity); | |
8451 } | |
8452 return kNotFound; | |
8453 } | |
8454 | |
8455 | |
8456 // Find entry for key otherwise return kNotFound. | |
8457 int StringDictionary::FindEntry(String* key) { | 8544 int StringDictionary::FindEntry(String* key) { |
8458 if (!key->IsSymbol()) { | 8545 if (!key->IsSymbol()) { |
8459 return HashTable<StringDictionaryShape, String*>::FindEntry(key); | 8546 return HashTable<StringDictionaryShape, String*>::FindEntry(key); |
8460 } | 8547 } |
8461 | 8548 |
8462 // Optimized for symbol key. Knowledge of the key type allows: | 8549 // Optimized for symbol key. Knowledge of the key type allows: |
8463 // 1. Move the check if the key is a symbol out of the loop. | 8550 // 1. Move the check if the key is a symbol out of the loop. |
8464 // 2. Avoid comparing hash codes in symbol to symbol comparision. | 8551 // 2. Avoid comparing hash codes in symbol to symbol comparision. |
8465 // 3. Detect a case when a dictionary key is not a symbol but the key is. | 8552 // 3. Detect a case when a dictionary key is not a symbol but the key is. |
8466 // In case of positive result the dictionary key may be replaced by | 8553 // In case of positive result the dictionary key may be replaced by |
(...skipping 21 matching lines...) Expand all Loading... |
8488 } | 8575 } |
8489 ASSERT(element->IsNull() || !String::cast(element)->Equals(key)); | 8576 ASSERT(element->IsNull() || !String::cast(element)->Equals(key)); |
8490 entry = NextProbe(entry, count++, capacity); | 8577 entry = NextProbe(entry, count++, capacity); |
8491 } | 8578 } |
8492 return kNotFound; | 8579 return kNotFound; |
8493 } | 8580 } |
8494 | 8581 |
8495 | 8582 |
8496 template<typename Shape, typename Key> | 8583 template<typename Shape, typename Key> |
8497 MaybeObject* HashTable<Shape, Key>::EnsureCapacity(int n, Key key) { | 8584 MaybeObject* HashTable<Shape, Key>::EnsureCapacity(int n, Key key) { |
| 8585 Heap* heap = GetHeap(); |
8498 int capacity = Capacity(); | 8586 int capacity = Capacity(); |
8499 int nof = NumberOfElements() + n; | 8587 int nof = NumberOfElements() + n; |
8500 int nod = NumberOfDeletedElements(); | 8588 int nod = NumberOfDeletedElements(); |
8501 // Return if: | 8589 // Return if: |
8502 // 50% is still free after adding n elements and | 8590 // 50% is still free after adding n elements and |
8503 // at most 50% of the free elements are deleted elements. | 8591 // at most 50% of the free elements are deleted elements. |
8504 if (nod <= (capacity - nof) >> 1) { | 8592 if (nod <= (capacity - nof) >> 1) { |
8505 int needed_free = nof >> 1; | 8593 int needed_free = nof >> 1; |
8506 if (nof + needed_free <= capacity) return this; | 8594 if (nof + needed_free <= capacity) return this; |
8507 } | 8595 } |
8508 | 8596 |
8509 const int kMinCapacityForPretenure = 256; | 8597 const int kMinCapacityForPretenure = 256; |
8510 bool pretenure = | 8598 bool pretenure = |
8511 (capacity > kMinCapacityForPretenure) && !Heap::InNewSpace(this); | 8599 (capacity > kMinCapacityForPretenure) && !heap->InNewSpace(this); |
8512 Object* obj; | 8600 Object* obj; |
8513 { MaybeObject* maybe_obj = | 8601 { MaybeObject* maybe_obj = |
8514 Allocate(nof * 2, pretenure ? TENURED : NOT_TENURED); | 8602 Allocate(nof * 2, pretenure ? TENURED : NOT_TENURED); |
8515 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 8603 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
8516 } | 8604 } |
8517 | 8605 |
8518 AssertNoAllocation no_gc; | 8606 AssertNoAllocation no_gc; |
8519 HashTable* table = HashTable::cast(obj); | 8607 HashTable* table = HashTable::cast(obj); |
8520 WriteBarrierMode mode = table->GetWriteBarrierMode(no_gc); | 8608 WriteBarrierMode mode = table->GetWriteBarrierMode(no_gc); |
8521 | 8609 |
(...skipping 111 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8633 template | 8721 template |
8634 int Dictionary<StringDictionaryShape, String*>::NumberOfEnumElements(); | 8722 int Dictionary<StringDictionaryShape, String*>::NumberOfEnumElements(); |
8635 | 8723 |
8636 template | 8724 template |
8637 int HashTable<NumberDictionaryShape, uint32_t>::FindEntry(uint32_t); | 8725 int HashTable<NumberDictionaryShape, uint32_t>::FindEntry(uint32_t); |
8638 | 8726 |
8639 | 8727 |
8640 // Collates undefined and unexisting elements below limit from position | 8728 // Collates undefined and unexisting elements below limit from position |
8641 // zero of the elements. The object stays in Dictionary mode. | 8729 // zero of the elements. The object stays in Dictionary mode. |
8642 MaybeObject* JSObject::PrepareSlowElementsForSort(uint32_t limit) { | 8730 MaybeObject* JSObject::PrepareSlowElementsForSort(uint32_t limit) { |
| 8731 Heap* heap = GetHeap(); |
8643 ASSERT(HasDictionaryElements()); | 8732 ASSERT(HasDictionaryElements()); |
8644 // Must stay in dictionary mode, either because of requires_slow_elements, | 8733 // Must stay in dictionary mode, either because of requires_slow_elements, |
8645 // or because we are not going to sort (and therefore compact) all of the | 8734 // or because we are not going to sort (and therefore compact) all of the |
8646 // elements. | 8735 // elements. |
8647 NumberDictionary* dict = element_dictionary(); | 8736 NumberDictionary* dict = element_dictionary(); |
8648 HeapNumber* result_double = NULL; | 8737 HeapNumber* result_double = NULL; |
8649 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { | 8738 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { |
8650 // Allocate space for result before we start mutating the object. | 8739 // Allocate space for result before we start mutating the object. |
8651 Object* new_double; | 8740 Object* new_double; |
8652 { MaybeObject* maybe_new_double = Heap::AllocateHeapNumber(0.0); | 8741 { MaybeObject* maybe_new_double = heap->AllocateHeapNumber(0.0); |
8653 if (!maybe_new_double->ToObject(&new_double)) return maybe_new_double; | 8742 if (!maybe_new_double->ToObject(&new_double)) return maybe_new_double; |
8654 } | 8743 } |
8655 result_double = HeapNumber::cast(new_double); | 8744 result_double = HeapNumber::cast(new_double); |
8656 } | 8745 } |
8657 | 8746 |
8658 Object* obj; | 8747 Object* obj; |
8659 { MaybeObject* maybe_obj = | 8748 { MaybeObject* maybe_obj = |
8660 NumberDictionary::Allocate(dict->NumberOfElements()); | 8749 NumberDictionary::Allocate(dict->NumberOfElements()); |
8661 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 8750 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
8662 } | 8751 } |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8708 } | 8797 } |
8709 | 8798 |
8710 uint32_t result = pos; | 8799 uint32_t result = pos; |
8711 PropertyDetails no_details = PropertyDetails(NONE, NORMAL); | 8800 PropertyDetails no_details = PropertyDetails(NONE, NORMAL); |
8712 while (undefs > 0) { | 8801 while (undefs > 0) { |
8713 if (pos > static_cast<uint32_t>(Smi::kMaxValue)) { | 8802 if (pos > static_cast<uint32_t>(Smi::kMaxValue)) { |
8714 // Adding an entry with the key beyond smi-range requires | 8803 // Adding an entry with the key beyond smi-range requires |
8715 // allocation. Bailout. | 8804 // allocation. Bailout. |
8716 return Smi::FromInt(-1); | 8805 return Smi::FromInt(-1); |
8717 } | 8806 } |
8718 new_dict->AddNumberEntry(pos, Heap::undefined_value(), no_details)-> | 8807 new_dict->AddNumberEntry(pos, heap->undefined_value(), no_details)-> |
8719 ToObjectUnchecked(); | 8808 ToObjectUnchecked(); |
8720 pos++; | 8809 pos++; |
8721 undefs--; | 8810 undefs--; |
8722 } | 8811 } |
8723 | 8812 |
8724 set_elements(new_dict); | 8813 set_elements(new_dict); |
8725 | 8814 |
8726 if (result <= static_cast<uint32_t>(Smi::kMaxValue)) { | 8815 if (result <= static_cast<uint32_t>(Smi::kMaxValue)) { |
8727 return Smi::FromInt(static_cast<int>(result)); | 8816 return Smi::FromInt(static_cast<int>(result)); |
8728 } | 8817 } |
8729 | 8818 |
8730 ASSERT_NE(NULL, result_double); | 8819 ASSERT_NE(NULL, result_double); |
8731 result_double->set_value(static_cast<double>(result)); | 8820 result_double->set_value(static_cast<double>(result)); |
8732 return result_double; | 8821 return result_double; |
8733 } | 8822 } |
8734 | 8823 |
8735 | 8824 |
8736 // Collects all defined (non-hole) and non-undefined (array) elements at | 8825 // Collects all defined (non-hole) and non-undefined (array) elements at |
8737 // the start of the elements array. | 8826 // the start of the elements array. |
8738 // If the object is in dictionary mode, it is converted to fast elements | 8827 // If the object is in dictionary mode, it is converted to fast elements |
8739 // mode. | 8828 // mode. |
8740 MaybeObject* JSObject::PrepareElementsForSort(uint32_t limit) { | 8829 MaybeObject* JSObject::PrepareElementsForSort(uint32_t limit) { |
| 8830 Heap* heap = GetHeap(); |
8741 ASSERT(!HasExternalArrayElements()); | 8831 ASSERT(!HasExternalArrayElements()); |
8742 | 8832 |
8743 if (HasDictionaryElements()) { | 8833 if (HasDictionaryElements()) { |
8744 // Convert to fast elements containing only the existing properties. | 8834 // Convert to fast elements containing only the existing properties. |
8745 // Ordering is irrelevant, since we are going to sort anyway. | 8835 // Ordering is irrelevant, since we are going to sort anyway. |
8746 NumberDictionary* dict = element_dictionary(); | 8836 NumberDictionary* dict = element_dictionary(); |
8747 if (IsJSArray() || dict->requires_slow_elements() || | 8837 if (IsJSArray() || dict->requires_slow_elements() || |
8748 dict->max_number_key() >= limit) { | 8838 dict->max_number_key() >= limit) { |
8749 return PrepareSlowElementsForSort(limit); | 8839 return PrepareSlowElementsForSort(limit); |
8750 } | 8840 } |
8751 // Convert to fast elements. | 8841 // Convert to fast elements. |
8752 | 8842 |
8753 Object* obj; | 8843 Object* obj; |
8754 { MaybeObject* maybe_obj = map()->GetFastElementsMap(); | 8844 { MaybeObject* maybe_obj = map()->GetFastElementsMap(); |
8755 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 8845 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
8756 } | 8846 } |
8757 Map* new_map = Map::cast(obj); | 8847 Map* new_map = Map::cast(obj); |
8758 | 8848 |
8759 PretenureFlag tenure = Heap::InNewSpace(this) ? NOT_TENURED: TENURED; | 8849 PretenureFlag tenure = heap->InNewSpace(this) ? NOT_TENURED: TENURED; |
8760 Object* new_array; | 8850 Object* new_array; |
8761 { MaybeObject* maybe_new_array = | 8851 { MaybeObject* maybe_new_array = |
8762 Heap::AllocateFixedArray(dict->NumberOfElements(), tenure); | 8852 heap->AllocateFixedArray(dict->NumberOfElements(), tenure); |
8763 if (!maybe_new_array->ToObject(&new_array)) return maybe_new_array; | 8853 if (!maybe_new_array->ToObject(&new_array)) return maybe_new_array; |
8764 } | 8854 } |
8765 FixedArray* fast_elements = FixedArray::cast(new_array); | 8855 FixedArray* fast_elements = FixedArray::cast(new_array); |
8766 dict->CopyValuesTo(fast_elements); | 8856 dict->CopyValuesTo(fast_elements); |
8767 | 8857 |
8768 set_map(new_map); | 8858 set_map(new_map); |
8769 set_elements(fast_elements); | 8859 set_elements(fast_elements); |
8770 } else { | 8860 } else { |
8771 Object* obj; | 8861 Object* obj; |
8772 { MaybeObject* maybe_obj = EnsureWritableFastElements(); | 8862 { MaybeObject* maybe_obj = EnsureWritableFastElements(); |
(...skipping 12 matching lines...) Expand all Loading... |
8785 } | 8875 } |
8786 if (limit == 0) { | 8876 if (limit == 0) { |
8787 return Smi::FromInt(0); | 8877 return Smi::FromInt(0); |
8788 } | 8878 } |
8789 | 8879 |
8790 HeapNumber* result_double = NULL; | 8880 HeapNumber* result_double = NULL; |
8791 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { | 8881 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { |
8792 // Pessimistically allocate space for return value before | 8882 // Pessimistically allocate space for return value before |
8793 // we start mutating the array. | 8883 // we start mutating the array. |
8794 Object* new_double; | 8884 Object* new_double; |
8795 { MaybeObject* maybe_new_double = Heap::AllocateHeapNumber(0.0); | 8885 { MaybeObject* maybe_new_double = heap->AllocateHeapNumber(0.0); |
8796 if (!maybe_new_double->ToObject(&new_double)) return maybe_new_double; | 8886 if (!maybe_new_double->ToObject(&new_double)) return maybe_new_double; |
8797 } | 8887 } |
8798 result_double = HeapNumber::cast(new_double); | 8888 result_double = HeapNumber::cast(new_double); |
8799 } | 8889 } |
8800 | 8890 |
8801 AssertNoAllocation no_alloc; | 8891 AssertNoAllocation no_alloc; |
8802 | 8892 |
8803 // Split elements into defined, undefined and the_hole, in that order. | 8893 // Split elements into defined, undefined and the_hole, in that order. |
8804 // Only count locations for undefined and the hole, and fill them afterwards. | 8894 // Only count locations for undefined and the hole, and fill them afterwards. |
8805 WriteBarrierMode write_barrier = elements->GetWriteBarrierMode(no_alloc); | 8895 WriteBarrierMode write_barrier = elements->GetWriteBarrierMode(no_alloc); |
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
8879 // converted to a number type further up in the call chain. | 8969 // converted to a number type further up in the call chain. |
8880 ASSERT(value->IsUndefined()); | 8970 ASSERT(value->IsUndefined()); |
8881 } | 8971 } |
8882 set(index, clamped_value); | 8972 set(index, clamped_value); |
8883 } | 8973 } |
8884 return Smi::FromInt(clamped_value); | 8974 return Smi::FromInt(clamped_value); |
8885 } | 8975 } |
8886 | 8976 |
8887 | 8977 |
8888 template<typename ExternalArrayClass, typename ValueType> | 8978 template<typename ExternalArrayClass, typename ValueType> |
8889 static MaybeObject* ExternalArrayIntSetter(ExternalArrayClass* receiver, | 8979 static MaybeObject* ExternalArrayIntSetter(Heap* heap, |
| 8980 ExternalArrayClass* receiver, |
8890 uint32_t index, | 8981 uint32_t index, |
8891 Object* value) { | 8982 Object* value) { |
8892 ValueType cast_value = 0; | 8983 ValueType cast_value = 0; |
8893 if (index < static_cast<uint32_t>(receiver->length())) { | 8984 if (index < static_cast<uint32_t>(receiver->length())) { |
8894 if (value->IsSmi()) { | 8985 if (value->IsSmi()) { |
8895 int int_value = Smi::cast(value)->value(); | 8986 int int_value = Smi::cast(value)->value(); |
8896 cast_value = static_cast<ValueType>(int_value); | 8987 cast_value = static_cast<ValueType>(int_value); |
8897 } else if (value->IsHeapNumber()) { | 8988 } else if (value->IsHeapNumber()) { |
8898 double double_value = HeapNumber::cast(value)->value(); | 8989 double double_value = HeapNumber::cast(value)->value(); |
8899 cast_value = static_cast<ValueType>(DoubleToInt32(double_value)); | 8990 cast_value = static_cast<ValueType>(DoubleToInt32(double_value)); |
8900 } else { | 8991 } else { |
8901 // Clamp undefined to zero (default). All other types have been | 8992 // Clamp undefined to zero (default). All other types have been |
8902 // converted to a number type further up in the call chain. | 8993 // converted to a number type further up in the call chain. |
8903 ASSERT(value->IsUndefined()); | 8994 ASSERT(value->IsUndefined()); |
8904 } | 8995 } |
8905 receiver->set(index, cast_value); | 8996 receiver->set(index, cast_value); |
8906 } | 8997 } |
8907 return Heap::NumberFromInt32(cast_value); | 8998 return heap->NumberFromInt32(cast_value); |
8908 } | 8999 } |
8909 | 9000 |
8910 | 9001 |
8911 MaybeObject* ExternalByteArray::SetValue(uint32_t index, Object* value) { | 9002 MaybeObject* ExternalByteArray::SetValue(uint32_t index, Object* value) { |
8912 return ExternalArrayIntSetter<ExternalByteArray, int8_t> | 9003 return ExternalArrayIntSetter<ExternalByteArray, int8_t> |
8913 (this, index, value); | 9004 (GetHeap(), this, index, value); |
8914 } | 9005 } |
8915 | 9006 |
8916 | 9007 |
8917 MaybeObject* ExternalUnsignedByteArray::SetValue(uint32_t index, | 9008 MaybeObject* ExternalUnsignedByteArray::SetValue(uint32_t index, |
8918 Object* value) { | 9009 Object* value) { |
8919 return ExternalArrayIntSetter<ExternalUnsignedByteArray, uint8_t> | 9010 return ExternalArrayIntSetter<ExternalUnsignedByteArray, uint8_t> |
8920 (this, index, value); | 9011 (GetHeap(), this, index, value); |
8921 } | 9012 } |
8922 | 9013 |
8923 | 9014 |
8924 MaybeObject* ExternalShortArray::SetValue(uint32_t index, | 9015 MaybeObject* ExternalShortArray::SetValue(uint32_t index, |
8925 Object* value) { | 9016 Object* value) { |
8926 return ExternalArrayIntSetter<ExternalShortArray, int16_t> | 9017 return ExternalArrayIntSetter<ExternalShortArray, int16_t> |
8927 (this, index, value); | 9018 (GetHeap(), this, index, value); |
8928 } | 9019 } |
8929 | 9020 |
8930 | 9021 |
8931 MaybeObject* ExternalUnsignedShortArray::SetValue(uint32_t index, | 9022 MaybeObject* ExternalUnsignedShortArray::SetValue(uint32_t index, |
8932 Object* value) { | 9023 Object* value) { |
8933 return ExternalArrayIntSetter<ExternalUnsignedShortArray, uint16_t> | 9024 return ExternalArrayIntSetter<ExternalUnsignedShortArray, uint16_t> |
8934 (this, index, value); | 9025 (GetHeap(), this, index, value); |
8935 } | 9026 } |
8936 | 9027 |
8937 | 9028 |
8938 MaybeObject* ExternalIntArray::SetValue(uint32_t index, Object* value) { | 9029 MaybeObject* ExternalIntArray::SetValue(uint32_t index, Object* value) { |
8939 return ExternalArrayIntSetter<ExternalIntArray, int32_t> | 9030 return ExternalArrayIntSetter<ExternalIntArray, int32_t> |
8940 (this, index, value); | 9031 (GetHeap(), this, index, value); |
8941 } | 9032 } |
8942 | 9033 |
8943 | 9034 |
8944 MaybeObject* ExternalUnsignedIntArray::SetValue(uint32_t index, Object* value) { | 9035 MaybeObject* ExternalUnsignedIntArray::SetValue(uint32_t index, Object* value) { |
8945 uint32_t cast_value = 0; | 9036 uint32_t cast_value = 0; |
| 9037 Heap* heap = GetHeap(); |
8946 if (index < static_cast<uint32_t>(length())) { | 9038 if (index < static_cast<uint32_t>(length())) { |
8947 if (value->IsSmi()) { | 9039 if (value->IsSmi()) { |
8948 int int_value = Smi::cast(value)->value(); | 9040 int int_value = Smi::cast(value)->value(); |
8949 cast_value = static_cast<uint32_t>(int_value); | 9041 cast_value = static_cast<uint32_t>(int_value); |
8950 } else if (value->IsHeapNumber()) { | 9042 } else if (value->IsHeapNumber()) { |
8951 double double_value = HeapNumber::cast(value)->value(); | 9043 double double_value = HeapNumber::cast(value)->value(); |
8952 cast_value = static_cast<uint32_t>(DoubleToUint32(double_value)); | 9044 cast_value = static_cast<uint32_t>(DoubleToUint32(double_value)); |
8953 } else { | 9045 } else { |
8954 // Clamp undefined to zero (default). All other types have been | 9046 // Clamp undefined to zero (default). All other types have been |
8955 // converted to a number type further up in the call chain. | 9047 // converted to a number type further up in the call chain. |
8956 ASSERT(value->IsUndefined()); | 9048 ASSERT(value->IsUndefined()); |
8957 } | 9049 } |
8958 set(index, cast_value); | 9050 set(index, cast_value); |
8959 } | 9051 } |
8960 return Heap::NumberFromUint32(cast_value); | 9052 return heap->NumberFromUint32(cast_value); |
8961 } | 9053 } |
8962 | 9054 |
8963 | 9055 |
8964 MaybeObject* ExternalFloatArray::SetValue(uint32_t index, Object* value) { | 9056 MaybeObject* ExternalFloatArray::SetValue(uint32_t index, Object* value) { |
8965 float cast_value = 0; | 9057 float cast_value = 0; |
| 9058 Heap* heap = GetHeap(); |
8966 if (index < static_cast<uint32_t>(length())) { | 9059 if (index < static_cast<uint32_t>(length())) { |
8967 if (value->IsSmi()) { | 9060 if (value->IsSmi()) { |
8968 int int_value = Smi::cast(value)->value(); | 9061 int int_value = Smi::cast(value)->value(); |
8969 cast_value = static_cast<float>(int_value); | 9062 cast_value = static_cast<float>(int_value); |
8970 } else if (value->IsHeapNumber()) { | 9063 } else if (value->IsHeapNumber()) { |
8971 double double_value = HeapNumber::cast(value)->value(); | 9064 double double_value = HeapNumber::cast(value)->value(); |
8972 cast_value = static_cast<float>(double_value); | 9065 cast_value = static_cast<float>(double_value); |
8973 } else { | 9066 } else { |
8974 // Clamp undefined to zero (default). All other types have been | 9067 // Clamp undefined to zero (default). All other types have been |
8975 // converted to a number type further up in the call chain. | 9068 // converted to a number type further up in the call chain. |
8976 ASSERT(value->IsUndefined()); | 9069 ASSERT(value->IsUndefined()); |
8977 } | 9070 } |
8978 set(index, cast_value); | 9071 set(index, cast_value); |
8979 } | 9072 } |
8980 return Heap::AllocateHeapNumber(cast_value); | 9073 return heap->AllocateHeapNumber(cast_value); |
8981 } | 9074 } |
8982 | 9075 |
8983 | 9076 |
8984 JSGlobalPropertyCell* GlobalObject::GetPropertyCell(LookupResult* result) { | 9077 JSGlobalPropertyCell* GlobalObject::GetPropertyCell(LookupResult* result) { |
8985 ASSERT(!HasFastProperties()); | 9078 ASSERT(!HasFastProperties()); |
8986 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); | 9079 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); |
8987 return JSGlobalPropertyCell::cast(value); | 9080 return JSGlobalPropertyCell::cast(value); |
8988 } | 9081 } |
8989 | 9082 |
8990 | 9083 |
8991 MaybeObject* GlobalObject::EnsurePropertyCell(String* name) { | 9084 MaybeObject* GlobalObject::EnsurePropertyCell(String* name) { |
8992 ASSERT(!HasFastProperties()); | 9085 ASSERT(!HasFastProperties()); |
| 9086 Heap* heap = GetHeap(); |
8993 int entry = property_dictionary()->FindEntry(name); | 9087 int entry = property_dictionary()->FindEntry(name); |
8994 if (entry == StringDictionary::kNotFound) { | 9088 if (entry == StringDictionary::kNotFound) { |
8995 Object* cell; | 9089 Object* cell; |
8996 { MaybeObject* maybe_cell = | 9090 { MaybeObject* maybe_cell = |
8997 Heap::AllocateJSGlobalPropertyCell(Heap::the_hole_value()); | 9091 heap->AllocateJSGlobalPropertyCell(heap->the_hole_value()); |
8998 if (!maybe_cell->ToObject(&cell)) return maybe_cell; | 9092 if (!maybe_cell->ToObject(&cell)) return maybe_cell; |
8999 } | 9093 } |
9000 PropertyDetails details(NONE, NORMAL); | 9094 PropertyDetails details(NONE, NORMAL); |
9001 details = details.AsDeleted(); | 9095 details = details.AsDeleted(); |
9002 Object* dictionary; | 9096 Object* dictionary; |
9003 { MaybeObject* maybe_dictionary = | 9097 { MaybeObject* maybe_dictionary = |
9004 property_dictionary()->Add(name, cell, details); | 9098 property_dictionary()->Add(name, cell, details); |
9005 if (!maybe_dictionary->ToObject(&dictionary)) return maybe_dictionary; | 9099 if (!maybe_dictionary->ToObject(&dictionary)) return maybe_dictionary; |
9006 } | 9100 } |
9007 set_properties(StringDictionary::cast(dictionary)); | 9101 set_properties(StringDictionary::cast(dictionary)); |
(...skipping 151 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9159 // Add the new symbol and return it along with the symbol table. | 9253 // Add the new symbol and return it along with the symbol table. |
9160 entry = table->FindInsertionEntry(key->Hash()); | 9254 entry = table->FindInsertionEntry(key->Hash()); |
9161 table->set(EntryToIndex(entry), symbol); | 9255 table->set(EntryToIndex(entry), symbol); |
9162 table->ElementAdded(); | 9256 table->ElementAdded(); |
9163 *s = symbol; | 9257 *s = symbol; |
9164 return table; | 9258 return table; |
9165 } | 9259 } |
9166 | 9260 |
9167 | 9261 |
9168 Object* CompilationCacheTable::Lookup(String* src) { | 9262 Object* CompilationCacheTable::Lookup(String* src) { |
| 9263 Heap* heap = GetHeap(); |
9169 StringKey key(src); | 9264 StringKey key(src); |
9170 int entry = FindEntry(&key); | 9265 int entry = FindEntry(&key); |
9171 if (entry == kNotFound) return Heap::undefined_value(); | 9266 if (entry == kNotFound) return heap->undefined_value(); |
9172 return get(EntryToIndex(entry) + 1); | 9267 return get(EntryToIndex(entry) + 1); |
9173 } | 9268 } |
9174 | 9269 |
9175 | 9270 |
9176 Object* CompilationCacheTable::LookupEval(String* src, | 9271 Object* CompilationCacheTable::LookupEval(String* src, |
9177 Context* context, | 9272 Context* context, |
9178 StrictModeFlag strict_mode) { | 9273 StrictModeFlag strict_mode) { |
9179 StringSharedKey key(src, context->closure()->shared(), strict_mode); | 9274 StringSharedKey key(src, context->closure()->shared(), strict_mode); |
9180 int entry = FindEntry(&key); | 9275 int entry = FindEntry(&key); |
9181 if (entry == kNotFound) return Heap::undefined_value(); | 9276 if (entry == kNotFound) return GetHeap()->undefined_value(); |
9182 return get(EntryToIndex(entry) + 1); | 9277 return get(EntryToIndex(entry) + 1); |
9183 } | 9278 } |
9184 | 9279 |
9185 | 9280 |
9186 Object* CompilationCacheTable::LookupRegExp(String* src, | 9281 Object* CompilationCacheTable::LookupRegExp(String* src, |
9187 JSRegExp::Flags flags) { | 9282 JSRegExp::Flags flags) { |
| 9283 Heap* heap = GetHeap(); |
9188 RegExpKey key(src, flags); | 9284 RegExpKey key(src, flags); |
9189 int entry = FindEntry(&key); | 9285 int entry = FindEntry(&key); |
9190 if (entry == kNotFound) return Heap::undefined_value(); | 9286 if (entry == kNotFound) return heap->undefined_value(); |
9191 return get(EntryToIndex(entry) + 1); | 9287 return get(EntryToIndex(entry) + 1); |
9192 } | 9288 } |
9193 | 9289 |
9194 | 9290 |
9195 MaybeObject* CompilationCacheTable::Put(String* src, Object* value) { | 9291 MaybeObject* CompilationCacheTable::Put(String* src, Object* value) { |
9196 StringKey key(src); | 9292 StringKey key(src); |
9197 Object* obj; | 9293 Object* obj; |
9198 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); | 9294 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); |
9199 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 9295 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
9200 } | 9296 } |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9251 // We store the value in the key slot, and compare the search key | 9347 // We store the value in the key slot, and compare the search key |
9252 // to the stored value with a custon IsMatch function during lookups. | 9348 // to the stored value with a custon IsMatch function during lookups. |
9253 cache->set(EntryToIndex(entry), value); | 9349 cache->set(EntryToIndex(entry), value); |
9254 cache->set(EntryToIndex(entry) + 1, value); | 9350 cache->set(EntryToIndex(entry) + 1, value); |
9255 cache->ElementAdded(); | 9351 cache->ElementAdded(); |
9256 return cache; | 9352 return cache; |
9257 } | 9353 } |
9258 | 9354 |
9259 | 9355 |
9260 void CompilationCacheTable::Remove(Object* value) { | 9356 void CompilationCacheTable::Remove(Object* value) { |
| 9357 Object* null_value = GetHeap()->null_value(); |
9261 for (int entry = 0, size = Capacity(); entry < size; entry++) { | 9358 for (int entry = 0, size = Capacity(); entry < size; entry++) { |
9262 int entry_index = EntryToIndex(entry); | 9359 int entry_index = EntryToIndex(entry); |
9263 int value_index = entry_index + 1; | 9360 int value_index = entry_index + 1; |
9264 if (get(value_index) == value) { | 9361 if (get(value_index) == value) { |
9265 fast_set(this, entry_index, Heap::null_value()); | 9362 fast_set(this, entry_index, null_value); |
9266 fast_set(this, value_index, Heap::null_value()); | 9363 fast_set(this, value_index, null_value); |
9267 ElementRemoved(); | 9364 ElementRemoved(); |
9268 } | 9365 } |
9269 } | 9366 } |
9270 return; | 9367 return; |
9271 } | 9368 } |
9272 | 9369 |
9273 | 9370 |
9274 // SymbolsKey used for HashTable where key is array of symbols. | 9371 // SymbolsKey used for HashTable where key is array of symbols. |
9275 class SymbolsKey : public HashTableKey { | 9372 class SymbolsKey : public HashTableKey { |
9276 public: | 9373 public: |
(...skipping 22 matching lines...) Expand all Loading... |
9299 } | 9396 } |
9300 | 9397 |
9301 Object* AsObject() { return symbols_; } | 9398 Object* AsObject() { return symbols_; } |
9302 | 9399 |
9303 private: | 9400 private: |
9304 FixedArray* symbols_; | 9401 FixedArray* symbols_; |
9305 }; | 9402 }; |
9306 | 9403 |
9307 | 9404 |
9308 Object* MapCache::Lookup(FixedArray* array) { | 9405 Object* MapCache::Lookup(FixedArray* array) { |
| 9406 Heap* heap = GetHeap(); |
9309 SymbolsKey key(array); | 9407 SymbolsKey key(array); |
9310 int entry = FindEntry(&key); | 9408 int entry = FindEntry(&key); |
9311 if (entry == kNotFound) return Heap::undefined_value(); | 9409 if (entry == kNotFound) return heap->undefined_value(); |
9312 return get(EntryToIndex(entry) + 1); | 9410 return get(EntryToIndex(entry) + 1); |
9313 } | 9411 } |
9314 | 9412 |
9315 | 9413 |
9316 MaybeObject* MapCache::Put(FixedArray* array, Map* value) { | 9414 MaybeObject* MapCache::Put(FixedArray* array, Map* value) { |
9317 SymbolsKey key(array); | 9415 SymbolsKey key(array); |
9318 Object* obj; | 9416 Object* obj; |
9319 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); | 9417 { MaybeObject* maybe_obj = EnsureCapacity(1, &key); |
9320 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 9418 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
9321 } | 9419 } |
(...skipping 16 matching lines...) Expand all Loading... |
9338 } | 9436 } |
9339 // Initialize the next enumeration index. | 9437 // Initialize the next enumeration index. |
9340 Dictionary<Shape, Key>::cast(obj)-> | 9438 Dictionary<Shape, Key>::cast(obj)-> |
9341 SetNextEnumerationIndex(PropertyDetails::kInitialIndex); | 9439 SetNextEnumerationIndex(PropertyDetails::kInitialIndex); |
9342 return obj; | 9440 return obj; |
9343 } | 9441 } |
9344 | 9442 |
9345 | 9443 |
9346 template<typename Shape, typename Key> | 9444 template<typename Shape, typename Key> |
9347 MaybeObject* Dictionary<Shape, Key>::GenerateNewEnumerationIndices() { | 9445 MaybeObject* Dictionary<Shape, Key>::GenerateNewEnumerationIndices() { |
| 9446 Heap* heap = Dictionary<Shape, Key>::GetHeap(); |
9348 int length = HashTable<Shape, Key>::NumberOfElements(); | 9447 int length = HashTable<Shape, Key>::NumberOfElements(); |
9349 | 9448 |
9350 // Allocate and initialize iteration order array. | 9449 // Allocate and initialize iteration order array. |
9351 Object* obj; | 9450 Object* obj; |
9352 { MaybeObject* maybe_obj = Heap::AllocateFixedArray(length); | 9451 { MaybeObject* maybe_obj = heap->AllocateFixedArray(length); |
9353 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 9452 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
9354 } | 9453 } |
9355 FixedArray* iteration_order = FixedArray::cast(obj); | 9454 FixedArray* iteration_order = FixedArray::cast(obj); |
9356 for (int i = 0; i < length; i++) { | 9455 for (int i = 0; i < length; i++) { |
9357 iteration_order->set(i, Smi::FromInt(i)); | 9456 iteration_order->set(i, Smi::FromInt(i)); |
9358 } | 9457 } |
9359 | 9458 |
9360 // Allocate array with enumeration order. | 9459 // Allocate array with enumeration order. |
9361 { MaybeObject* maybe_obj = Heap::AllocateFixedArray(length); | 9460 { MaybeObject* maybe_obj = heap->AllocateFixedArray(length); |
9362 if (!maybe_obj->ToObject(&obj)) return maybe_obj; | 9461 if (!maybe_obj->ToObject(&obj)) return maybe_obj; |
9363 } | 9462 } |
9364 FixedArray* enumeration_order = FixedArray::cast(obj); | 9463 FixedArray* enumeration_order = FixedArray::cast(obj); |
9365 | 9464 |
9366 // Fill the enumeration order array with property details. | 9465 // Fill the enumeration order array with property details. |
9367 int capacity = HashTable<Shape, Key>::Capacity(); | 9466 int capacity = HashTable<Shape, Key>::Capacity(); |
9368 int pos = 0; | 9467 int pos = 0; |
9369 for (int i = 0; i < capacity; i++) { | 9468 for (int i = 0; i < capacity; i++) { |
9370 if (Dictionary<Shape, Key>::IsKey(Dictionary<Shape, Key>::KeyAt(i))) { | 9469 if (Dictionary<Shape, Key>::IsKey(Dictionary<Shape, Key>::KeyAt(i))) { |
9371 enumeration_order->set(pos++, Smi::FromInt(DetailsAt(i).index())); | 9470 enumeration_order->set(pos++, Smi::FromInt(DetailsAt(i).index())); |
(...skipping 40 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9412 } | 9511 } |
9413 } | 9512 } |
9414 return HashTable<Shape, Key>::EnsureCapacity(n, key); | 9513 return HashTable<Shape, Key>::EnsureCapacity(n, key); |
9415 } | 9514 } |
9416 | 9515 |
9417 | 9516 |
9418 void NumberDictionary::RemoveNumberEntries(uint32_t from, uint32_t to) { | 9517 void NumberDictionary::RemoveNumberEntries(uint32_t from, uint32_t to) { |
9419 // Do nothing if the interval [from, to) is empty. | 9518 // Do nothing if the interval [from, to) is empty. |
9420 if (from >= to) return; | 9519 if (from >= to) return; |
9421 | 9520 |
| 9521 Heap* heap = GetHeap(); |
9422 int removed_entries = 0; | 9522 int removed_entries = 0; |
9423 Object* sentinel = Heap::null_value(); | 9523 Object* sentinel = heap->null_value(); |
9424 int capacity = Capacity(); | 9524 int capacity = Capacity(); |
9425 for (int i = 0; i < capacity; i++) { | 9525 for (int i = 0; i < capacity; i++) { |
9426 Object* key = KeyAt(i); | 9526 Object* key = KeyAt(i); |
9427 if (key->IsNumber()) { | 9527 if (key->IsNumber()) { |
9428 uint32_t number = static_cast<uint32_t>(key->Number()); | 9528 uint32_t number = static_cast<uint32_t>(key->Number()); |
9429 if (from <= number && number < to) { | 9529 if (from <= number && number < to) { |
9430 SetEntry(i, sentinel, sentinel, Smi::FromInt(0)); | 9530 SetEntry(i, sentinel, sentinel, Smi::FromInt(0)); |
9431 removed_entries++; | 9531 removed_entries++; |
9432 } | 9532 } |
9433 } | 9533 } |
9434 } | 9534 } |
9435 | 9535 |
9436 // Update the number of elements. | 9536 // Update the number of elements. |
9437 ElementsRemoved(removed_entries); | 9537 ElementsRemoved(removed_entries); |
9438 } | 9538 } |
9439 | 9539 |
9440 | 9540 |
9441 template<typename Shape, typename Key> | 9541 template<typename Shape, typename Key> |
9442 Object* Dictionary<Shape, Key>::DeleteProperty(int entry, | 9542 Object* Dictionary<Shape, Key>::DeleteProperty(int entry, |
9443 JSObject::DeleteMode mode) { | 9543 JSObject::DeleteMode mode) { |
| 9544 Heap* heap = Dictionary<Shape, Key>::GetHeap(); |
9444 PropertyDetails details = DetailsAt(entry); | 9545 PropertyDetails details = DetailsAt(entry); |
9445 // Ignore attributes if forcing a deletion. | 9546 // Ignore attributes if forcing a deletion. |
9446 if (details.IsDontDelete() && mode != JSObject::FORCE_DELETION) { | 9547 if (details.IsDontDelete() && mode != JSObject::FORCE_DELETION) { |
9447 return Heap::false_value(); | 9548 return heap->false_value(); |
9448 } | 9549 } |
9449 SetEntry(entry, Heap::null_value(), Heap::null_value(), Smi::FromInt(0)); | 9550 SetEntry(entry, heap->null_value(), heap->null_value(), Smi::FromInt(0)); |
9450 HashTable<Shape, Key>::ElementRemoved(); | 9551 HashTable<Shape, Key>::ElementRemoved(); |
9451 return Heap::true_value(); | 9552 return heap->true_value(); |
9452 } | 9553 } |
9453 | 9554 |
9454 | 9555 |
9455 template<typename Shape, typename Key> | 9556 template<typename Shape, typename Key> |
9456 MaybeObject* Dictionary<Shape, Key>::AtPut(Key key, Object* value) { | 9557 MaybeObject* Dictionary<Shape, Key>::AtPut(Key key, Object* value) { |
9457 int entry = this->FindEntry(key); | 9558 int entry = this->FindEntry(key); |
9458 | 9559 |
9459 // If the entry is present set the value; | 9560 // If the entry is present set the value; |
9460 if (entry != Dictionary<Shape, Key>::kNotFound) { | 9561 if (entry != Dictionary<Shape, Key>::kNotFound) { |
9461 ValueAtPut(entry, value); | 9562 ValueAtPut(entry, value); |
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9654 storage->set(index++, k); | 9755 storage->set(index++, k); |
9655 } | 9756 } |
9656 } | 9757 } |
9657 ASSERT(storage->length() >= index); | 9758 ASSERT(storage->length() >= index); |
9658 } | 9759 } |
9659 | 9760 |
9660 | 9761 |
9661 // Backwards lookup (slow). | 9762 // Backwards lookup (slow). |
9662 template<typename Shape, typename Key> | 9763 template<typename Shape, typename Key> |
9663 Object* Dictionary<Shape, Key>::SlowReverseLookup(Object* value) { | 9764 Object* Dictionary<Shape, Key>::SlowReverseLookup(Object* value) { |
| 9765 Heap* heap = Dictionary<Shape, Key>::GetHeap(); |
9664 int capacity = HashTable<Shape, Key>::Capacity(); | 9766 int capacity = HashTable<Shape, Key>::Capacity(); |
9665 for (int i = 0; i < capacity; i++) { | 9767 for (int i = 0; i < capacity; i++) { |
9666 Object* k = HashTable<Shape, Key>::KeyAt(i); | 9768 Object* k = HashTable<Shape, Key>::KeyAt(i); |
9667 if (Dictionary<Shape, Key>::IsKey(k)) { | 9769 if (Dictionary<Shape, Key>::IsKey(k)) { |
9668 Object* e = ValueAt(i); | 9770 Object* e = ValueAt(i); |
9669 if (e->IsJSGlobalPropertyCell()) { | 9771 if (e->IsJSGlobalPropertyCell()) { |
9670 e = JSGlobalPropertyCell::cast(e)->value(); | 9772 e = JSGlobalPropertyCell::cast(e)->value(); |
9671 } | 9773 } |
9672 if (e == value) return k; | 9774 if (e == value) return k; |
9673 } | 9775 } |
9674 } | 9776 } |
9675 return Heap::undefined_value(); | 9777 return heap->undefined_value(); |
9676 } | 9778 } |
9677 | 9779 |
9678 | 9780 |
9679 MaybeObject* StringDictionary::TransformPropertiesToFastFor( | 9781 MaybeObject* StringDictionary::TransformPropertiesToFastFor( |
9680 JSObject* obj, int unused_property_fields) { | 9782 JSObject* obj, int unused_property_fields) { |
| 9783 Heap* heap = GetHeap(); |
9681 // Make sure we preserve dictionary representation if there are too many | 9784 // Make sure we preserve dictionary representation if there are too many |
9682 // descriptors. | 9785 // descriptors. |
9683 if (NumberOfElements() > DescriptorArray::kMaxNumberOfDescriptors) return obj; | 9786 if (NumberOfElements() > DescriptorArray::kMaxNumberOfDescriptors) return obj; |
9684 | 9787 |
9685 // Figure out if it is necessary to generate new enumeration indices. | 9788 // Figure out if it is necessary to generate new enumeration indices. |
9686 int max_enumeration_index = | 9789 int max_enumeration_index = |
9687 NextEnumerationIndex() + | 9790 NextEnumerationIndex() + |
9688 (DescriptorArray::kMaxNumberOfDescriptors - | 9791 (DescriptorArray::kMaxNumberOfDescriptors - |
9689 NumberOfElements()); | 9792 NumberOfElements()); |
9690 if (!PropertyDetails::IsValidIndex(max_enumeration_index)) { | 9793 if (!PropertyDetails::IsValidIndex(max_enumeration_index)) { |
9691 Object* result; | 9794 Object* result; |
9692 { MaybeObject* maybe_result = GenerateNewEnumerationIndices(); | 9795 { MaybeObject* maybe_result = GenerateNewEnumerationIndices(); |
9693 if (!maybe_result->ToObject(&result)) return maybe_result; | 9796 if (!maybe_result->ToObject(&result)) return maybe_result; |
9694 } | 9797 } |
9695 } | 9798 } |
9696 | 9799 |
9697 int instance_descriptor_length = 0; | 9800 int instance_descriptor_length = 0; |
9698 int number_of_fields = 0; | 9801 int number_of_fields = 0; |
9699 | 9802 |
9700 // Compute the length of the instance descriptor. | 9803 // Compute the length of the instance descriptor. |
9701 int capacity = Capacity(); | 9804 int capacity = Capacity(); |
9702 for (int i = 0; i < capacity; i++) { | 9805 for (int i = 0; i < capacity; i++) { |
9703 Object* k = KeyAt(i); | 9806 Object* k = KeyAt(i); |
9704 if (IsKey(k)) { | 9807 if (IsKey(k)) { |
9705 Object* value = ValueAt(i); | 9808 Object* value = ValueAt(i); |
9706 PropertyType type = DetailsAt(i).type(); | 9809 PropertyType type = DetailsAt(i).type(); |
9707 ASSERT(type != FIELD); | 9810 ASSERT(type != FIELD); |
9708 instance_descriptor_length++; | 9811 instance_descriptor_length++; |
9709 if (type == NORMAL && | 9812 if (type == NORMAL && |
9710 (!value->IsJSFunction() || Heap::InNewSpace(value))) { | 9813 (!value->IsJSFunction() || heap->InNewSpace(value))) { |
9711 number_of_fields += 1; | 9814 number_of_fields += 1; |
9712 } | 9815 } |
9713 } | 9816 } |
9714 } | 9817 } |
9715 | 9818 |
9716 // Allocate the instance descriptor. | 9819 // Allocate the instance descriptor. |
9717 Object* descriptors_unchecked; | 9820 Object* descriptors_unchecked; |
9718 { MaybeObject* maybe_descriptors_unchecked = | 9821 { MaybeObject* maybe_descriptors_unchecked = |
9719 DescriptorArray::Allocate(instance_descriptor_length); | 9822 DescriptorArray::Allocate(instance_descriptor_length); |
9720 if (!maybe_descriptors_unchecked->ToObject(&descriptors_unchecked)) { | 9823 if (!maybe_descriptors_unchecked->ToObject(&descriptors_unchecked)) { |
9721 return maybe_descriptors_unchecked; | 9824 return maybe_descriptors_unchecked; |
9722 } | 9825 } |
9723 } | 9826 } |
9724 DescriptorArray* descriptors = DescriptorArray::cast(descriptors_unchecked); | 9827 DescriptorArray* descriptors = DescriptorArray::cast(descriptors_unchecked); |
9725 | 9828 |
9726 int inobject_props = obj->map()->inobject_properties(); | 9829 int inobject_props = obj->map()->inobject_properties(); |
9727 int number_of_allocated_fields = | 9830 int number_of_allocated_fields = |
9728 number_of_fields + unused_property_fields - inobject_props; | 9831 number_of_fields + unused_property_fields - inobject_props; |
9729 if (number_of_allocated_fields < 0) { | 9832 if (number_of_allocated_fields < 0) { |
9730 // There is enough inobject space for all fields (including unused). | 9833 // There is enough inobject space for all fields (including unused). |
9731 number_of_allocated_fields = 0; | 9834 number_of_allocated_fields = 0; |
9732 unused_property_fields = inobject_props - number_of_fields; | 9835 unused_property_fields = inobject_props - number_of_fields; |
9733 } | 9836 } |
9734 | 9837 |
9735 // Allocate the fixed array for the fields. | 9838 // Allocate the fixed array for the fields. |
9736 Object* fields; | 9839 Object* fields; |
9737 { MaybeObject* maybe_fields = | 9840 { MaybeObject* maybe_fields = |
9738 Heap::AllocateFixedArray(number_of_allocated_fields); | 9841 heap->AllocateFixedArray(number_of_allocated_fields); |
9739 if (!maybe_fields->ToObject(&fields)) return maybe_fields; | 9842 if (!maybe_fields->ToObject(&fields)) return maybe_fields; |
9740 } | 9843 } |
9741 | 9844 |
9742 // Fill in the instance descriptor and the fields. | 9845 // Fill in the instance descriptor and the fields. |
9743 int next_descriptor = 0; | 9846 int next_descriptor = 0; |
9744 int current_offset = 0; | 9847 int current_offset = 0; |
9745 for (int i = 0; i < capacity; i++) { | 9848 for (int i = 0; i < capacity; i++) { |
9746 Object* k = KeyAt(i); | 9849 Object* k = KeyAt(i); |
9747 if (IsKey(k)) { | 9850 if (IsKey(k)) { |
9748 Object* value = ValueAt(i); | 9851 Object* value = ValueAt(i); |
9749 // Ensure the key is a symbol before writing into the instance descriptor. | 9852 // Ensure the key is a symbol before writing into the instance descriptor. |
9750 Object* key; | 9853 Object* key; |
9751 { MaybeObject* maybe_key = Heap::LookupSymbol(String::cast(k)); | 9854 { MaybeObject* maybe_key = heap->LookupSymbol(String::cast(k)); |
9752 if (!maybe_key->ToObject(&key)) return maybe_key; | 9855 if (!maybe_key->ToObject(&key)) return maybe_key; |
9753 } | 9856 } |
9754 PropertyDetails details = DetailsAt(i); | 9857 PropertyDetails details = DetailsAt(i); |
9755 PropertyType type = details.type(); | 9858 PropertyType type = details.type(); |
9756 | 9859 |
9757 if (value->IsJSFunction() && !Heap::InNewSpace(value)) { | 9860 if (value->IsJSFunction() && !heap->InNewSpace(value)) { |
9758 ConstantFunctionDescriptor d(String::cast(key), | 9861 ConstantFunctionDescriptor d(String::cast(key), |
9759 JSFunction::cast(value), | 9862 JSFunction::cast(value), |
9760 details.attributes(), | 9863 details.attributes(), |
9761 details.index()); | 9864 details.index()); |
9762 descriptors->Set(next_descriptor++, &d); | 9865 descriptors->Set(next_descriptor++, &d); |
9763 } else if (type == NORMAL) { | 9866 } else if (type == NORMAL) { |
9764 if (current_offset < inobject_props) { | 9867 if (current_offset < inobject_props) { |
9765 obj->InObjectPropertyAtPut(current_offset, | 9868 obj->InObjectPropertyAtPut(current_offset, |
9766 value, | 9869 value, |
9767 UPDATE_WRITE_BARRIER); | 9870 UPDATE_WRITE_BARRIER); |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9818 | 9921 |
9819 // If there is no break point info object or no break points in the break | 9922 // If there is no break point info object or no break points in the break |
9820 // point info object there is no break point at this code position. | 9923 // point info object there is no break point at this code position. |
9821 if (break_point_info->IsUndefined()) return false; | 9924 if (break_point_info->IsUndefined()) return false; |
9822 return BreakPointInfo::cast(break_point_info)->GetBreakPointCount() > 0; | 9925 return BreakPointInfo::cast(break_point_info)->GetBreakPointCount() > 0; |
9823 } | 9926 } |
9824 | 9927 |
9825 | 9928 |
9826 // Get the break point info object for this code position. | 9929 // Get the break point info object for this code position. |
9827 Object* DebugInfo::GetBreakPointInfo(int code_position) { | 9930 Object* DebugInfo::GetBreakPointInfo(int code_position) { |
| 9931 Heap* heap = GetHeap(); |
9828 // Find the index of the break point info object for this code position. | 9932 // Find the index of the break point info object for this code position. |
9829 int index = GetBreakPointInfoIndex(code_position); | 9933 int index = GetBreakPointInfoIndex(code_position); |
9830 | 9934 |
9831 // Return the break point info object if any. | 9935 // Return the break point info object if any. |
9832 if (index == kNoBreakPointInfo) return Heap::undefined_value(); | 9936 if (index == kNoBreakPointInfo) return heap->undefined_value(); |
9833 return BreakPointInfo::cast(break_points()->get(index)); | 9937 return BreakPointInfo::cast(break_points()->get(index)); |
9834 } | 9938 } |
9835 | 9939 |
9836 | 9940 |
9837 // Clear a break point at the specified code position. | 9941 // Clear a break point at the specified code position. |
9838 void DebugInfo::ClearBreakPoint(Handle<DebugInfo> debug_info, | 9942 void DebugInfo::ClearBreakPoint(Handle<DebugInfo> debug_info, |
9839 int code_position, | 9943 int code_position, |
9840 Handle<Object> break_point_object) { | 9944 Handle<Object> break_point_object) { |
9841 Handle<Object> break_point_info(debug_info->GetBreakPointInfo(code_position)); | 9945 Handle<Object> break_point_info(debug_info->GetBreakPointInfo(code_position)); |
9842 if (break_point_info->IsUndefined()) return; | 9946 if (break_point_info->IsUndefined()) return; |
9843 BreakPointInfo::ClearBreakPoint( | 9947 BreakPointInfo::ClearBreakPoint( |
9844 Handle<BreakPointInfo>::cast(break_point_info), | 9948 Handle<BreakPointInfo>::cast(break_point_info), |
9845 break_point_object); | 9949 break_point_object); |
9846 } | 9950 } |
9847 | 9951 |
9848 | 9952 |
9849 void DebugInfo::SetBreakPoint(Handle<DebugInfo> debug_info, | 9953 void DebugInfo::SetBreakPoint(Handle<DebugInfo> debug_info, |
9850 int code_position, | 9954 int code_position, |
9851 int source_position, | 9955 int source_position, |
9852 int statement_position, | 9956 int statement_position, |
9853 Handle<Object> break_point_object) { | 9957 Handle<Object> break_point_object) { |
| 9958 Isolate* isolate = Isolate::Current(); |
9854 Handle<Object> break_point_info(debug_info->GetBreakPointInfo(code_position)); | 9959 Handle<Object> break_point_info(debug_info->GetBreakPointInfo(code_position)); |
9855 if (!break_point_info->IsUndefined()) { | 9960 if (!break_point_info->IsUndefined()) { |
9856 BreakPointInfo::SetBreakPoint( | 9961 BreakPointInfo::SetBreakPoint( |
9857 Handle<BreakPointInfo>::cast(break_point_info), | 9962 Handle<BreakPointInfo>::cast(break_point_info), |
9858 break_point_object); | 9963 break_point_object); |
9859 return; | 9964 return; |
9860 } | 9965 } |
9861 | 9966 |
9862 // Adding a new break point for a code position which did not have any | 9967 // Adding a new break point for a code position which did not have any |
9863 // break points before. Try to find a free slot. | 9968 // break points before. Try to find a free slot. |
9864 int index = kNoBreakPointInfo; | 9969 int index = kNoBreakPointInfo; |
9865 for (int i = 0; i < debug_info->break_points()->length(); i++) { | 9970 for (int i = 0; i < debug_info->break_points()->length(); i++) { |
9866 if (debug_info->break_points()->get(i)->IsUndefined()) { | 9971 if (debug_info->break_points()->get(i)->IsUndefined()) { |
9867 index = i; | 9972 index = i; |
9868 break; | 9973 break; |
9869 } | 9974 } |
9870 } | 9975 } |
9871 if (index == kNoBreakPointInfo) { | 9976 if (index == kNoBreakPointInfo) { |
9872 // No free slot - extend break point info array. | 9977 // No free slot - extend break point info array. |
9873 Handle<FixedArray> old_break_points = | 9978 Handle<FixedArray> old_break_points = |
9874 Handle<FixedArray>(FixedArray::cast(debug_info->break_points())); | 9979 Handle<FixedArray>(FixedArray::cast(debug_info->break_points())); |
9875 Handle<FixedArray> new_break_points = | 9980 Handle<FixedArray> new_break_points = |
9876 Factory::NewFixedArray(old_break_points->length() + | 9981 isolate->factory()->NewFixedArray( |
9877 Debug::kEstimatedNofBreakPointsInFunction); | 9982 old_break_points->length() + |
| 9983 Debug::kEstimatedNofBreakPointsInFunction); |
9878 | 9984 |
9879 debug_info->set_break_points(*new_break_points); | 9985 debug_info->set_break_points(*new_break_points); |
9880 for (int i = 0; i < old_break_points->length(); i++) { | 9986 for (int i = 0; i < old_break_points->length(); i++) { |
9881 new_break_points->set(i, old_break_points->get(i)); | 9987 new_break_points->set(i, old_break_points->get(i)); |
9882 } | 9988 } |
9883 index = old_break_points->length(); | 9989 index = old_break_points->length(); |
9884 } | 9990 } |
9885 ASSERT(index != kNoBreakPointInfo); | 9991 ASSERT(index != kNoBreakPointInfo); |
9886 | 9992 |
9887 // Allocate new BreakPointInfo object and set the break point. | 9993 // Allocate new BreakPointInfo object and set the break point. |
9888 Handle<BreakPointInfo> new_break_point_info = | 9994 Handle<BreakPointInfo> new_break_point_info = Handle<BreakPointInfo>::cast( |
9889 Handle<BreakPointInfo>::cast(Factory::NewStruct(BREAK_POINT_INFO_TYPE)); | 9995 isolate->factory()->NewStruct(BREAK_POINT_INFO_TYPE)); |
9890 new_break_point_info->set_code_position(Smi::FromInt(code_position)); | 9996 new_break_point_info->set_code_position(Smi::FromInt(code_position)); |
9891 new_break_point_info->set_source_position(Smi::FromInt(source_position)); | 9997 new_break_point_info->set_source_position(Smi::FromInt(source_position)); |
9892 new_break_point_info-> | 9998 new_break_point_info-> |
9893 set_statement_position(Smi::FromInt(statement_position)); | 9999 set_statement_position(Smi::FromInt(statement_position)); |
9894 new_break_point_info->set_break_point_objects(Heap::undefined_value()); | 10000 new_break_point_info->set_break_point_objects( |
| 10001 isolate->heap()->undefined_value()); |
9895 BreakPointInfo::SetBreakPoint(new_break_point_info, break_point_object); | 10002 BreakPointInfo::SetBreakPoint(new_break_point_info, break_point_object); |
9896 debug_info->break_points()->set(index, *new_break_point_info); | 10003 debug_info->break_points()->set(index, *new_break_point_info); |
9897 } | 10004 } |
9898 | 10005 |
9899 | 10006 |
9900 // Get the break point objects for a code position. | 10007 // Get the break point objects for a code position. |
9901 Object* DebugInfo::GetBreakPointObjects(int code_position) { | 10008 Object* DebugInfo::GetBreakPointObjects(int code_position) { |
| 10009 Heap* heap = GetHeap(); |
9902 Object* break_point_info = GetBreakPointInfo(code_position); | 10010 Object* break_point_info = GetBreakPointInfo(code_position); |
9903 if (break_point_info->IsUndefined()) { | 10011 if (break_point_info->IsUndefined()) { |
9904 return Heap::undefined_value(); | 10012 return heap->undefined_value(); |
9905 } | 10013 } |
9906 return BreakPointInfo::cast(break_point_info)->break_point_objects(); | 10014 return BreakPointInfo::cast(break_point_info)->break_point_objects(); |
9907 } | 10015 } |
9908 | 10016 |
9909 | 10017 |
9910 // Get the total number of break points. | 10018 // Get the total number of break points. |
9911 int DebugInfo::GetBreakPointCount() { | 10019 int DebugInfo::GetBreakPointCount() { |
9912 if (break_points()->IsUndefined()) return 0; | 10020 if (break_points()->IsUndefined()) return 0; |
9913 int count = 0; | 10021 int count = 0; |
9914 for (int i = 0; i < break_points()->length(); i++) { | 10022 for (int i = 0; i < break_points()->length(); i++) { |
9915 if (!break_points()->get(i)->IsUndefined()) { | 10023 if (!break_points()->get(i)->IsUndefined()) { |
9916 BreakPointInfo* break_point_info = | 10024 BreakPointInfo* break_point_info = |
9917 BreakPointInfo::cast(break_points()->get(i)); | 10025 BreakPointInfo::cast(break_points()->get(i)); |
9918 count += break_point_info->GetBreakPointCount(); | 10026 count += break_point_info->GetBreakPointCount(); |
9919 } | 10027 } |
9920 } | 10028 } |
9921 return count; | 10029 return count; |
9922 } | 10030 } |
9923 | 10031 |
9924 | 10032 |
9925 Object* DebugInfo::FindBreakPointInfo(Handle<DebugInfo> debug_info, | 10033 Object* DebugInfo::FindBreakPointInfo(Handle<DebugInfo> debug_info, |
9926 Handle<Object> break_point_object) { | 10034 Handle<Object> break_point_object) { |
9927 if (debug_info->break_points()->IsUndefined()) return Heap::undefined_value(); | 10035 Heap* heap = Isolate::Current()->heap(); |
| 10036 if (debug_info->break_points()->IsUndefined()) return heap->undefined_value(); |
9928 for (int i = 0; i < debug_info->break_points()->length(); i++) { | 10037 for (int i = 0; i < debug_info->break_points()->length(); i++) { |
9929 if (!debug_info->break_points()->get(i)->IsUndefined()) { | 10038 if (!debug_info->break_points()->get(i)->IsUndefined()) { |
9930 Handle<BreakPointInfo> break_point_info = | 10039 Handle<BreakPointInfo> break_point_info = |
9931 Handle<BreakPointInfo>(BreakPointInfo::cast( | 10040 Handle<BreakPointInfo>(BreakPointInfo::cast( |
9932 debug_info->break_points()->get(i))); | 10041 debug_info->break_points()->get(i))); |
9933 if (BreakPointInfo::HasBreakPointObject(break_point_info, | 10042 if (BreakPointInfo::HasBreakPointObject(break_point_info, |
9934 break_point_object)) { | 10043 break_point_object)) { |
9935 return *break_point_info; | 10044 return *break_point_info; |
9936 } | 10045 } |
9937 } | 10046 } |
9938 } | 10047 } |
9939 return Heap::undefined_value(); | 10048 return heap->undefined_value(); |
9940 } | 10049 } |
9941 | 10050 |
9942 | 10051 |
9943 // Find the index of the break point info object for the specified code | 10052 // Find the index of the break point info object for the specified code |
9944 // position. | 10053 // position. |
9945 int DebugInfo::GetBreakPointInfoIndex(int code_position) { | 10054 int DebugInfo::GetBreakPointInfoIndex(int code_position) { |
9946 if (break_points()->IsUndefined()) return kNoBreakPointInfo; | 10055 if (break_points()->IsUndefined()) return kNoBreakPointInfo; |
9947 for (int i = 0; i < break_points()->length(); i++) { | 10056 for (int i = 0; i < break_points()->length(); i++) { |
9948 if (!break_points()->get(i)->IsUndefined()) { | 10057 if (!break_points()->get(i)->IsUndefined()) { |
9949 BreakPointInfo* break_point_info = | 10058 BreakPointInfo* break_point_info = |
9950 BreakPointInfo::cast(break_points()->get(i)); | 10059 BreakPointInfo::cast(break_points()->get(i)); |
9951 if (break_point_info->code_position()->value() == code_position) { | 10060 if (break_point_info->code_position()->value() == code_position) { |
9952 return i; | 10061 return i; |
9953 } | 10062 } |
9954 } | 10063 } |
9955 } | 10064 } |
9956 return kNoBreakPointInfo; | 10065 return kNoBreakPointInfo; |
9957 } | 10066 } |
9958 | 10067 |
9959 | 10068 |
9960 // Remove the specified break point object. | 10069 // Remove the specified break point object. |
9961 void BreakPointInfo::ClearBreakPoint(Handle<BreakPointInfo> break_point_info, | 10070 void BreakPointInfo::ClearBreakPoint(Handle<BreakPointInfo> break_point_info, |
9962 Handle<Object> break_point_object) { | 10071 Handle<Object> break_point_object) { |
| 10072 Isolate* isolate = Isolate::Current(); |
9963 // If there are no break points just ignore. | 10073 // If there are no break points just ignore. |
9964 if (break_point_info->break_point_objects()->IsUndefined()) return; | 10074 if (break_point_info->break_point_objects()->IsUndefined()) return; |
9965 // If there is a single break point clear it if it is the same. | 10075 // If there is a single break point clear it if it is the same. |
9966 if (!break_point_info->break_point_objects()->IsFixedArray()) { | 10076 if (!break_point_info->break_point_objects()->IsFixedArray()) { |
9967 if (break_point_info->break_point_objects() == *break_point_object) { | 10077 if (break_point_info->break_point_objects() == *break_point_object) { |
9968 break_point_info->set_break_point_objects(Heap::undefined_value()); | 10078 break_point_info->set_break_point_objects( |
| 10079 isolate->heap()->undefined_value()); |
9969 } | 10080 } |
9970 return; | 10081 return; |
9971 } | 10082 } |
9972 // If there are multiple break points shrink the array | 10083 // If there are multiple break points shrink the array |
9973 ASSERT(break_point_info->break_point_objects()->IsFixedArray()); | 10084 ASSERT(break_point_info->break_point_objects()->IsFixedArray()); |
9974 Handle<FixedArray> old_array = | 10085 Handle<FixedArray> old_array = |
9975 Handle<FixedArray>( | 10086 Handle<FixedArray>( |
9976 FixedArray::cast(break_point_info->break_point_objects())); | 10087 FixedArray::cast(break_point_info->break_point_objects())); |
9977 Handle<FixedArray> new_array = | 10088 Handle<FixedArray> new_array = |
9978 Factory::NewFixedArray(old_array->length() - 1); | 10089 isolate->factory()->NewFixedArray(old_array->length() - 1); |
9979 int found_count = 0; | 10090 int found_count = 0; |
9980 for (int i = 0; i < old_array->length(); i++) { | 10091 for (int i = 0; i < old_array->length(); i++) { |
9981 if (old_array->get(i) == *break_point_object) { | 10092 if (old_array->get(i) == *break_point_object) { |
9982 ASSERT(found_count == 0); | 10093 ASSERT(found_count == 0); |
9983 found_count++; | 10094 found_count++; |
9984 } else { | 10095 } else { |
9985 new_array->set(i - found_count, old_array->get(i)); | 10096 new_array->set(i - found_count, old_array->get(i)); |
9986 } | 10097 } |
9987 } | 10098 } |
9988 // If the break point was found in the list change it. | 10099 // If the break point was found in the list change it. |
9989 if (found_count > 0) break_point_info->set_break_point_objects(*new_array); | 10100 if (found_count > 0) break_point_info->set_break_point_objects(*new_array); |
9990 } | 10101 } |
9991 | 10102 |
9992 | 10103 |
9993 // Add the specified break point object. | 10104 // Add the specified break point object. |
9994 void BreakPointInfo::SetBreakPoint(Handle<BreakPointInfo> break_point_info, | 10105 void BreakPointInfo::SetBreakPoint(Handle<BreakPointInfo> break_point_info, |
9995 Handle<Object> break_point_object) { | 10106 Handle<Object> break_point_object) { |
9996 // If there was no break point objects before just set it. | 10107 // If there was no break point objects before just set it. |
9997 if (break_point_info->break_point_objects()->IsUndefined()) { | 10108 if (break_point_info->break_point_objects()->IsUndefined()) { |
9998 break_point_info->set_break_point_objects(*break_point_object); | 10109 break_point_info->set_break_point_objects(*break_point_object); |
9999 return; | 10110 return; |
10000 } | 10111 } |
10001 // If the break point object is the same as before just ignore. | 10112 // If the break point object is the same as before just ignore. |
10002 if (break_point_info->break_point_objects() == *break_point_object) return; | 10113 if (break_point_info->break_point_objects() == *break_point_object) return; |
10003 // If there was one break point object before replace with array. | 10114 // If there was one break point object before replace with array. |
10004 if (!break_point_info->break_point_objects()->IsFixedArray()) { | 10115 if (!break_point_info->break_point_objects()->IsFixedArray()) { |
10005 Handle<FixedArray> array = Factory::NewFixedArray(2); | 10116 Handle<FixedArray> array = FACTORY->NewFixedArray(2); |
10006 array->set(0, break_point_info->break_point_objects()); | 10117 array->set(0, break_point_info->break_point_objects()); |
10007 array->set(1, *break_point_object); | 10118 array->set(1, *break_point_object); |
10008 break_point_info->set_break_point_objects(*array); | 10119 break_point_info->set_break_point_objects(*array); |
10009 return; | 10120 return; |
10010 } | 10121 } |
10011 // If there was more than one break point before extend array. | 10122 // If there was more than one break point before extend array. |
10012 Handle<FixedArray> old_array = | 10123 Handle<FixedArray> old_array = |
10013 Handle<FixedArray>( | 10124 Handle<FixedArray>( |
10014 FixedArray::cast(break_point_info->break_point_objects())); | 10125 FixedArray::cast(break_point_info->break_point_objects())); |
10015 Handle<FixedArray> new_array = | 10126 Handle<FixedArray> new_array = |
10016 Factory::NewFixedArray(old_array->length() + 1); | 10127 FACTORY->NewFixedArray(old_array->length() + 1); |
10017 for (int i = 0; i < old_array->length(); i++) { | 10128 for (int i = 0; i < old_array->length(); i++) { |
10018 // If the break point was there before just ignore. | 10129 // If the break point was there before just ignore. |
10019 if (old_array->get(i) == *break_point_object) return; | 10130 if (old_array->get(i) == *break_point_object) return; |
10020 new_array->set(i, old_array->get(i)); | 10131 new_array->set(i, old_array->get(i)); |
10021 } | 10132 } |
10022 // Add the new break point. | 10133 // Add the new break point. |
10023 new_array->set(old_array->length(), *break_point_object); | 10134 new_array->set(old_array->length(), *break_point_object); |
10024 break_point_info->set_break_point_objects(*new_array); | 10135 break_point_info->set_break_point_objects(*new_array); |
10025 } | 10136 } |
10026 | 10137 |
(...skipping 24 matching lines...) Expand all Loading... |
10051 if (break_point_objects()->IsUndefined()) return 0; | 10162 if (break_point_objects()->IsUndefined()) return 0; |
10052 // Single beak point. | 10163 // Single beak point. |
10053 if (!break_point_objects()->IsFixedArray()) return 1; | 10164 if (!break_point_objects()->IsFixedArray()) return 1; |
10054 // Multiple break points. | 10165 // Multiple break points. |
10055 return FixedArray::cast(break_point_objects())->length(); | 10166 return FixedArray::cast(break_point_objects())->length(); |
10056 } | 10167 } |
10057 #endif | 10168 #endif |
10058 | 10169 |
10059 | 10170 |
10060 } } // namespace v8::internal | 10171 } } // namespace v8::internal |
OLD | NEW |