| OLD | NEW |
| 1 // Copyright 2006-2009 the V8 project authors. All rights reserved. | 1 // Copyright 2006-2009 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 25 matching lines...) Expand all Loading... |
| 36 #include "macro-assembler.h" | 36 #include "macro-assembler.h" |
| 37 #include "scanner.h" | 37 #include "scanner.h" |
| 38 #include "scopeinfo.h" | 38 #include "scopeinfo.h" |
| 39 #include "string-stream.h" | 39 #include "string-stream.h" |
| 40 #include "utils.h" | 40 #include "utils.h" |
| 41 | 41 |
| 42 #ifdef ENABLE_DISASSEMBLER | 42 #ifdef ENABLE_DISASSEMBLER |
| 43 #include "disassembler.h" | 43 #include "disassembler.h" |
| 44 #endif | 44 #endif |
| 45 | 45 |
| 46 | |
| 47 namespace v8 { | 46 namespace v8 { |
| 48 namespace internal { | 47 namespace internal { |
| 49 | 48 |
| 50 // Getters and setters are stored in a fixed array property. These are | 49 // Getters and setters are stored in a fixed array property. These are |
| 51 // constants for their indices. | 50 // constants for their indices. |
| 52 const int kGetterIndex = 0; | 51 const int kGetterIndex = 0; |
| 53 const int kSetterIndex = 1; | 52 const int kSetterIndex = 1; |
| 54 | 53 |
| 55 | 54 |
| 56 static Object* CreateJSValue(JSFunction* constructor, Object* value) { | 55 static Object* CreateJSValue(JSFunction* constructor, Object* value) { |
| 57 Object* result = HEAP->AllocateJSObject(constructor); | 56 Object* result = constructor->GetHeap()->AllocateJSObject(constructor); |
| 58 if (result->IsFailure()) return result; | 57 if (result->IsFailure()) return result; |
| 59 JSValue::cast(result)->set_value(value); | 58 JSValue::cast(result)->set_value(value); |
| 60 return result; | 59 return result; |
| 61 } | 60 } |
| 62 | 61 |
| 63 | 62 |
| 64 Object* Object::ToObject(Context* global_context) { | 63 Object* Object::ToObject(Context* global_context) { |
| 65 if (IsNumber()) { | 64 if (IsNumber()) { |
| 66 return CreateJSValue(global_context->number_function(), this); | 65 return CreateJSValue(global_context->number_function(), this); |
| 67 } else if (IsBoolean()) { | 66 } else if (IsBoolean()) { |
| 68 return CreateJSValue(global_context->boolean_function(), this); | 67 return CreateJSValue(global_context->boolean_function(), this); |
| 69 } else if (IsString()) { | 68 } else if (IsString()) { |
| 70 return CreateJSValue(global_context->string_function(), this); | 69 return CreateJSValue(global_context->string_function(), this); |
| 71 } | 70 } |
| 72 ASSERT(IsJSObject()); | 71 ASSERT(IsJSObject()); |
| 73 return this; | 72 return this; |
| 74 } | 73 } |
| 75 | 74 |
| 76 | 75 |
| 77 Object* Object::ToObject() { | 76 Object* Object::ToObject() { |
| 78 Context* global_context = Isolate::Current()->context()->global_context(); | |
| 79 if (IsJSObject()) { | 77 if (IsJSObject()) { |
| 80 return this; | 78 return this; |
| 81 } else if (IsNumber()) { | 79 } else if (IsNumber()) { |
| 80 Isolate* isolate = Isolate::Current(); |
| 81 Context* global_context = isolate->context()->global_context(); |
| 82 return CreateJSValue(global_context->number_function(), this); | 82 return CreateJSValue(global_context->number_function(), this); |
| 83 } else if (IsBoolean()) { | 83 } else if (IsBoolean()) { |
| 84 Heap* heap = HeapObject::cast(this)->GetHeap(); |
| 85 Context* global_context = heap->isolate()->context()->global_context(); |
| 84 return CreateJSValue(global_context->boolean_function(), this); | 86 return CreateJSValue(global_context->boolean_function(), this); |
| 85 } else if (IsString()) { | 87 } else if (IsString()) { |
| 88 Heap* heap = HeapObject::cast(this)->GetHeap(); |
| 89 Context* global_context = heap->isolate()->context()->global_context(); |
| 86 return CreateJSValue(global_context->string_function(), this); | 90 return CreateJSValue(global_context->string_function(), this); |
| 87 } | 91 } |
| 88 | 92 |
| 89 // Throw a type error. | 93 // Throw a type error. |
| 90 return Failure::InternalError(); | 94 return Failure::InternalError(); |
| 91 } | 95 } |
| 92 | 96 |
| 93 | 97 |
| 94 Object* Object::ToBoolean() { | 98 Object* Object::ToBoolean() { |
| 95 if (IsTrue()) return HEAP->true_value(); | 99 if (IsTrue()) return this; |
| 96 if (IsFalse()) return HEAP->false_value(); | 100 if (IsFalse()) return this; |
| 97 if (IsSmi()) { | 101 if (IsSmi()) { |
| 98 return HEAP->ToBoolean(Smi::cast(this)->value() != 0); | 102 return Isolate::Current()->heap()->ToBoolean(Smi::cast(this)->value() != 0); |
| 99 } | 103 } |
| 100 if (IsUndefined() || IsNull()) return HEAP->false_value(); | 104 if (IsUndefined() || IsNull()) { |
| 105 return HeapObject::cast(this)->GetHeap()->false_value(); |
| 106 } |
| 101 // Undetectable object is false | 107 // Undetectable object is false |
| 102 if (IsUndetectableObject()) { | 108 if (IsUndetectableObject()) { |
| 103 return HEAP->false_value(); | 109 return HeapObject::cast(this)->GetHeap()->false_value(); |
| 104 } | 110 } |
| 105 if (IsString()) { | 111 if (IsString()) { |
| 106 return HEAP->ToBoolean(String::cast(this)->length() != 0); | 112 return HeapObject::cast(this)->GetHeap()->ToBoolean( |
| 113 String::cast(this)->length() != 0); |
| 107 } | 114 } |
| 108 if (IsHeapNumber()) { | 115 if (IsHeapNumber()) { |
| 109 return HeapNumber::cast(this)->HeapNumberToBoolean(); | 116 return HeapNumber::cast(this)->HeapNumberToBoolean(); |
| 110 } | 117 } |
| 111 return HEAP->true_value(); | 118 return Isolate::Current()->heap()->true_value(); |
| 112 } | 119 } |
| 113 | 120 |
| 114 | 121 |
| 115 void Object::Lookup(String* name, LookupResult* result) { | 122 void Object::Lookup(String* name, LookupResult* result) { |
| 116 if (IsJSObject()) return JSObject::cast(this)->Lookup(name, result); | 123 if (IsJSObject()) return JSObject::cast(this)->Lookup(name, result); |
| 117 Object* holder = NULL; | 124 Object* holder = NULL; |
| 118 Context* global_context = Isolate::Current()->context()->global_context(); | |
| 119 if (IsString()) { | 125 if (IsString()) { |
| 126 Heap* heap = HeapObject::cast(this)->GetHeap(); |
| 127 Context* global_context = heap->isolate()->context()->global_context(); |
| 120 holder = global_context->string_function()->instance_prototype(); | 128 holder = global_context->string_function()->instance_prototype(); |
| 121 } else if (IsNumber()) { | 129 } else if (IsNumber()) { |
| 130 Heap* heap = Isolate::Current()->heap(); |
| 131 Context* global_context = heap->isolate()->context()->global_context(); |
| 122 holder = global_context->number_function()->instance_prototype(); | 132 holder = global_context->number_function()->instance_prototype(); |
| 123 } else if (IsBoolean()) { | 133 } else if (IsBoolean()) { |
| 134 Heap* heap = HeapObject::cast(this)->GetHeap(); |
| 135 Context* global_context = heap->isolate()->context()->global_context(); |
| 124 holder = global_context->boolean_function()->instance_prototype(); | 136 holder = global_context->boolean_function()->instance_prototype(); |
| 125 } | 137 } |
| 126 ASSERT(holder != NULL); // Cannot handle null or undefined. | 138 ASSERT(holder != NULL); // Cannot handle null or undefined. |
| 127 JSObject::cast(holder)->Lookup(name, result); | 139 JSObject::cast(holder)->Lookup(name, result); |
| 128 } | 140 } |
| 129 | 141 |
| 130 | 142 |
| 131 Object* Object::GetPropertyWithReceiver(Object* receiver, | 143 Object* Object::GetPropertyWithReceiver(Object* receiver, |
| 132 String* name, | 144 String* name, |
| 133 PropertyAttributes* attributes) { | 145 PropertyAttributes* attributes) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 147 // data structure used to store the callbacks. Eventually proxy | 159 // data structure used to store the callbacks. Eventually proxy |
| 148 // callbacks should be phased out. | 160 // callbacks should be phased out. |
| 149 if (structure->IsProxy()) { | 161 if (structure->IsProxy()) { |
| 150 AccessorDescriptor* callback = | 162 AccessorDescriptor* callback = |
| 151 reinterpret_cast<AccessorDescriptor*>(Proxy::cast(structure)->proxy()); | 163 reinterpret_cast<AccessorDescriptor*>(Proxy::cast(structure)->proxy()); |
| 152 Object* value = (callback->getter)(receiver, callback->data); | 164 Object* value = (callback->getter)(receiver, callback->data); |
| 153 RETURN_IF_SCHEDULED_EXCEPTION(); | 165 RETURN_IF_SCHEDULED_EXCEPTION(); |
| 154 return value; | 166 return value; |
| 155 } | 167 } |
| 156 | 168 |
| 169 Heap* heap = name->GetHeap(); |
| 170 |
| 157 // api style callbacks. | 171 // api style callbacks. |
| 158 if (structure->IsAccessorInfo()) { | 172 if (structure->IsAccessorInfo()) { |
| 159 AccessorInfo* data = AccessorInfo::cast(structure); | 173 AccessorInfo* data = AccessorInfo::cast(structure); |
| 160 Object* fun_obj = data->getter(); | 174 Object* fun_obj = data->getter(); |
| 161 v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj); | 175 v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj); |
| 162 HandleScope scope; | 176 HandleScope scope; |
| 163 JSObject* self = JSObject::cast(receiver); | 177 JSObject* self = JSObject::cast(receiver); |
| 164 JSObject* holder_handle = JSObject::cast(holder); | 178 JSObject* holder_handle = JSObject::cast(holder); |
| 165 Handle<String> key(name); | 179 Handle<String> key(name); |
| 166 LOG(ApiNamedPropertyAccess("load", self, name)); | 180 LOG(ApiNamedPropertyAccess("load", self, name)); |
| 167 CustomArguments args(data->data(), self, holder_handle); | 181 CustomArguments args(data->data(), self, holder_handle); |
| 168 v8::AccessorInfo info(args.end()); | 182 v8::AccessorInfo info(args.end()); |
| 169 v8::Handle<v8::Value> result; | 183 v8::Handle<v8::Value> result; |
| 170 { | 184 { |
| 171 // Leaving JavaScript. | 185 // Leaving JavaScript. |
| 172 VMState state(EXTERNAL); | 186 VMState state(EXTERNAL); |
| 173 result = call_fun(v8::Utils::ToLocal(key), info); | 187 result = call_fun(v8::Utils::ToLocal(key), info); |
| 174 } | 188 } |
| 175 RETURN_IF_SCHEDULED_EXCEPTION(); | 189 RETURN_IF_SCHEDULED_EXCEPTION(); |
| 176 if (result.IsEmpty()) return HEAP->undefined_value(); | 190 if (result.IsEmpty()) { |
| 191 return heap->undefined_value(); |
| 192 } |
| 177 return *v8::Utils::OpenHandle(*result); | 193 return *v8::Utils::OpenHandle(*result); |
| 178 } | 194 } |
| 179 | 195 |
| 180 // __defineGetter__ callback | 196 // __defineGetter__ callback |
| 181 if (structure->IsFixedArray()) { | 197 if (structure->IsFixedArray()) { |
| 182 Object* getter = FixedArray::cast(structure)->get(kGetterIndex); | 198 Object* getter = FixedArray::cast(structure)->get(kGetterIndex); |
| 183 if (getter->IsJSFunction()) { | 199 if (getter->IsJSFunction()) { |
| 184 return Object::GetPropertyWithDefinedGetter(receiver, | 200 return Object::GetPropertyWithDefinedGetter(receiver, |
| 185 JSFunction::cast(getter)); | 201 JSFunction::cast(getter)); |
| 186 } | 202 } |
| 187 // Getter is not a function. | 203 // Getter is not a function. |
| 188 return HEAP->undefined_value(); | 204 return heap->undefined_value(); |
| 189 } | 205 } |
| 190 | 206 |
| 191 UNREACHABLE(); | 207 UNREACHABLE(); |
| 192 return NULL; | 208 return NULL; |
| 193 } | 209 } |
| 194 | 210 |
| 195 | 211 |
| 196 Object* Object::GetPropertyWithDefinedGetter(Object* receiver, | 212 Object* Object::GetPropertyWithDefinedGetter(Object* receiver, |
| 197 JSFunction* getter) { | 213 JSFunction* getter) { |
| 198 HandleScope scope; | 214 HandleScope scope; |
| 199 Handle<JSFunction> fun(JSFunction::cast(getter)); | 215 Handle<JSFunction> fun(JSFunction::cast(getter)); |
| 200 Handle<Object> self(receiver); | 216 Handle<Object> self(receiver); |
| 201 #ifdef ENABLE_DEBUGGER_SUPPORT | 217 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 202 Debug* debug = Isolate::Current()->debug(); | 218 Debug* debug = fun->GetHeap()->isolate()->debug(); |
| 203 // Handle stepping into a getter if step into is active. | 219 // Handle stepping into a getter if step into is active. |
| 204 if (debug->StepInActive()) { | 220 if (debug->StepInActive()) { |
| 205 debug->HandleStepIn(fun, Handle<Object>::null(), 0, false); | 221 debug->HandleStepIn(fun, Handle<Object>::null(), 0, false); |
| 206 } | 222 } |
| 207 #endif | 223 #endif |
| 208 bool has_pending_exception; | 224 bool has_pending_exception; |
| 209 Handle<Object> result = | 225 Handle<Object> result = |
| 210 Execution::Call(fun, self, 0, NULL, &has_pending_exception); | 226 Execution::Call(fun, self, 0, NULL, &has_pending_exception); |
| 211 // Check for pending exception and return the result. | 227 // Check for pending exception and return the result. |
| 212 if (has_pending_exception) return Failure::Exception(); | 228 if (has_pending_exception) return Failure::Exception(); |
| 213 return *result; | 229 return *result; |
| 214 } | 230 } |
| 215 | 231 |
| 216 | 232 |
| 217 // Only deal with CALLBACKS and INTERCEPTOR | 233 // Only deal with CALLBACKS and INTERCEPTOR |
| 218 Object* JSObject::GetPropertyWithFailedAccessCheck( | 234 Object* JSObject::GetPropertyWithFailedAccessCheck( |
| 219 Object* receiver, | 235 Object* receiver, |
| 220 LookupResult* result, | 236 LookupResult* result, |
| 221 String* name, | 237 String* name, |
| 222 PropertyAttributes* attributes) { | 238 PropertyAttributes* attributes) { |
| 239 Heap* heap = name->GetHeap(); |
| 223 if (result->IsProperty()) { | 240 if (result->IsProperty()) { |
| 224 switch (result->type()) { | 241 switch (result->type()) { |
| 225 case CALLBACKS: { | 242 case CALLBACKS: { |
| 226 // Only allow API accessors. | 243 // Only allow API accessors. |
| 227 Object* obj = result->GetCallbackObject(); | 244 Object* obj = result->GetCallbackObject(); |
| 228 if (obj->IsAccessorInfo()) { | 245 if (obj->IsAccessorInfo()) { |
| 229 AccessorInfo* info = AccessorInfo::cast(obj); | 246 AccessorInfo* info = AccessorInfo::cast(obj); |
| 230 if (info->all_can_read()) { | 247 if (info->all_can_read()) { |
| 231 *attributes = result->GetAttributes(); | 248 *attributes = result->GetAttributes(); |
| 232 return GetPropertyWithCallback(receiver, | 249 return GetPropertyWithCallback(receiver, |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 264 } | 281 } |
| 265 break; | 282 break; |
| 266 } | 283 } |
| 267 default: | 284 default: |
| 268 UNREACHABLE(); | 285 UNREACHABLE(); |
| 269 } | 286 } |
| 270 } | 287 } |
| 271 | 288 |
| 272 // No accessible property found. | 289 // No accessible property found. |
| 273 *attributes = ABSENT; | 290 *attributes = ABSENT; |
| 274 Isolate::Current()->ReportFailedAccessCheck(this, v8::ACCESS_GET); | 291 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_GET); |
| 275 return HEAP->undefined_value(); | 292 return heap->undefined_value(); |
| 276 } | 293 } |
| 277 | 294 |
| 278 | 295 |
| 279 PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck( | 296 PropertyAttributes JSObject::GetPropertyAttributeWithFailedAccessCheck( |
| 280 Object* receiver, | 297 Object* receiver, |
| 281 LookupResult* result, | 298 LookupResult* result, |
| 282 String* name, | 299 String* name, |
| 283 bool continue_search) { | 300 bool continue_search) { |
| 301 Heap* heap = name->GetHeap(); |
| 284 if (result->IsProperty()) { | 302 if (result->IsProperty()) { |
| 285 switch (result->type()) { | 303 switch (result->type()) { |
| 286 case CALLBACKS: { | 304 case CALLBACKS: { |
| 287 // Only allow API accessors. | 305 // Only allow API accessors. |
| 288 Object* obj = result->GetCallbackObject(); | 306 Object* obj = result->GetCallbackObject(); |
| 289 if (obj->IsAccessorInfo()) { | 307 if (obj->IsAccessorInfo()) { |
| 290 AccessorInfo* info = AccessorInfo::cast(obj); | 308 AccessorInfo* info = AccessorInfo::cast(obj); |
| 291 if (info->all_can_read()) { | 309 if (info->all_can_read()) { |
| 292 return result->GetAttributes(); | 310 return result->GetAttributes(); |
| 293 } | 311 } |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 327 continue_search); | 345 continue_search); |
| 328 } | 346 } |
| 329 break; | 347 break; |
| 330 } | 348 } |
| 331 | 349 |
| 332 default: | 350 default: |
| 333 UNREACHABLE(); | 351 UNREACHABLE(); |
| 334 } | 352 } |
| 335 } | 353 } |
| 336 | 354 |
| 337 Isolate::Current()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 355 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 338 return ABSENT; | 356 return ABSENT; |
| 339 } | 357 } |
| 340 | 358 |
| 341 | 359 |
| 342 Object* JSObject::GetNormalizedProperty(LookupResult* result) { | 360 Object* JSObject::GetNormalizedProperty(LookupResult* result) { |
| 343 ASSERT(!HasFastProperties()); | 361 ASSERT(!HasFastProperties()); |
| 344 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); | 362 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); |
| 345 if (IsGlobalObject()) { | 363 if (IsGlobalObject()) { |
| 346 value = JSGlobalPropertyCell::cast(value)->value(); | 364 value = JSGlobalPropertyCell::cast(value)->value(); |
| 347 } | 365 } |
| (...skipping 13 matching lines...) Expand all Loading... |
| 361 property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value); | 379 property_dictionary()->ValueAtPut(result->GetDictionaryEntry(), value); |
| 362 } | 380 } |
| 363 return value; | 381 return value; |
| 364 } | 382 } |
| 365 | 383 |
| 366 | 384 |
| 367 Object* JSObject::SetNormalizedProperty(String* name, | 385 Object* JSObject::SetNormalizedProperty(String* name, |
| 368 Object* value, | 386 Object* value, |
| 369 PropertyDetails details) { | 387 PropertyDetails details) { |
| 370 ASSERT(!HasFastProperties()); | 388 ASSERT(!HasFastProperties()); |
| 389 Heap* heap = name->GetHeap(); |
| 371 int entry = property_dictionary()->FindEntry(name); | 390 int entry = property_dictionary()->FindEntry(name); |
| 372 if (entry == StringDictionary::kNotFound) { | 391 if (entry == StringDictionary::kNotFound) { |
| 373 Object* store_value = value; | 392 Object* store_value = value; |
| 374 if (IsGlobalObject()) { | 393 if (IsGlobalObject()) { |
| 375 store_value = HEAP->AllocateJSGlobalPropertyCell(value); | 394 store_value = heap->AllocateJSGlobalPropertyCell(value); |
| 376 if (store_value->IsFailure()) return store_value; | 395 if (store_value->IsFailure()) return store_value; |
| 377 } | 396 } |
| 378 Object* dict = property_dictionary()->Add(name, store_value, details); | 397 Object* dict = property_dictionary()->Add(name, store_value, details); |
| 379 if (dict->IsFailure()) return dict; | 398 if (dict->IsFailure()) return dict; |
| 380 set_properties(StringDictionary::cast(dict)); | 399 set_properties(StringDictionary::cast(dict)); |
| 381 return value; | 400 return value; |
| 382 } | 401 } |
| 383 // Preserve enumeration index. | 402 // Preserve enumeration index. |
| 384 details = PropertyDetails(details.attributes(), | 403 details = PropertyDetails(details.attributes(), |
| 385 details.type(), | 404 details.type(), |
| 386 property_dictionary()->DetailsAt(entry).index()); | 405 property_dictionary()->DetailsAt(entry).index()); |
| 387 if (IsGlobalObject()) { | 406 if (IsGlobalObject()) { |
| 388 JSGlobalPropertyCell* cell = | 407 JSGlobalPropertyCell* cell = |
| 389 JSGlobalPropertyCell::cast(property_dictionary()->ValueAt(entry)); | 408 JSGlobalPropertyCell::cast(property_dictionary()->ValueAt(entry)); |
| 390 cell->set_value(value); | 409 cell->set_value(value); |
| 391 // Please note we have to update the property details. | 410 // Please note we have to update the property details. |
| 392 property_dictionary()->DetailsAtPut(entry, details); | 411 property_dictionary()->DetailsAtPut(entry, details); |
| 393 } else { | 412 } else { |
| 394 property_dictionary()->SetEntry(entry, name, value, details); | 413 property_dictionary()->SetEntry(entry, name, value, details); |
| 395 } | 414 } |
| 396 return value; | 415 return value; |
| 397 } | 416 } |
| 398 | 417 |
| 399 | 418 |
| 400 Object* JSObject::DeleteNormalizedProperty(String* name, DeleteMode mode) { | 419 Object* JSObject::DeleteNormalizedProperty(String* name, DeleteMode mode) { |
| 401 ASSERT(!HasFastProperties()); | 420 ASSERT(!HasFastProperties()); |
| 421 Heap* heap = GetHeap(); |
| 402 StringDictionary* dictionary = property_dictionary(); | 422 StringDictionary* dictionary = property_dictionary(); |
| 403 int entry = dictionary->FindEntry(name); | 423 int entry = dictionary->FindEntry(name); |
| 404 if (entry != StringDictionary::kNotFound) { | 424 if (entry != StringDictionary::kNotFound) { |
| 405 // If we have a global object set the cell to the hole. | 425 // If we have a global object set the cell to the hole. |
| 406 if (IsGlobalObject()) { | 426 if (IsGlobalObject()) { |
| 407 PropertyDetails details = dictionary->DetailsAt(entry); | 427 PropertyDetails details = dictionary->DetailsAt(entry); |
| 408 if (details.IsDontDelete()) { | 428 if (details.IsDontDelete()) { |
| 409 if (mode != FORCE_DELETION) return HEAP->false_value(); | 429 if (mode != FORCE_DELETION) return heap->false_value(); |
| 410 // When forced to delete global properties, we have to make a | 430 // When forced to delete global properties, we have to make a |
| 411 // map change to invalidate any ICs that think they can load | 431 // map change to invalidate any ICs that think they can load |
| 412 // from the DontDelete cell without checking if it contains | 432 // from the DontDelete cell without checking if it contains |
| 413 // the hole value. | 433 // the hole value. |
| 414 Object* new_map = map()->CopyDropDescriptors(); | 434 Object* new_map = map()->CopyDropDescriptors(); |
| 415 if (new_map->IsFailure()) return new_map; | 435 if (new_map->IsFailure()) return new_map; |
| 416 set_map(Map::cast(new_map)); | 436 set_map(Map::cast(new_map)); |
| 417 } | 437 } |
| 418 JSGlobalPropertyCell* cell = | 438 JSGlobalPropertyCell* cell = |
| 419 JSGlobalPropertyCell::cast(dictionary->ValueAt(entry)); | 439 JSGlobalPropertyCell::cast(dictionary->ValueAt(entry)); |
| 420 cell->set_value(HEAP->the_hole_value()); | 440 cell->set_value(heap->the_hole_value()); |
| 421 dictionary->DetailsAtPut(entry, details.AsDeleted()); | 441 dictionary->DetailsAtPut(entry, details.AsDeleted()); |
| 422 } else { | 442 } else { |
| 423 return dictionary->DeleteProperty(entry, mode); | 443 return dictionary->DeleteProperty(entry, mode); |
| 424 } | 444 } |
| 425 } | 445 } |
| 426 return HEAP->true_value(); | 446 return heap->true_value(); |
| 427 } | 447 } |
| 428 | 448 |
| 429 | 449 |
| 430 bool JSObject::IsDirty() { | 450 bool JSObject::IsDirty() { |
| 431 Object* cons_obj = map()->constructor(); | 451 Object* cons_obj = map()->constructor(); |
| 432 if (!cons_obj->IsJSFunction()) | 452 if (!cons_obj->IsJSFunction()) |
| 433 return true; | 453 return true; |
| 434 JSFunction* fun = JSFunction::cast(cons_obj); | 454 JSFunction* fun = JSFunction::cast(cons_obj); |
| 435 if (!fun->shared()->IsApiFunction()) | 455 if (!fun->shared()->IsApiFunction()) |
| 436 return true; | 456 return true; |
| 437 // If the object is fully fast case and has the same map it was | 457 // If the object is fully fast case and has the same map it was |
| 438 // created with then no changes can have been made to it. | 458 // created with then no changes can have been made to it. |
| 439 return map() != fun->initial_map() | 459 return map() != fun->initial_map() |
| 440 || !HasFastElements() | 460 || !HasFastElements() |
| 441 || !HasFastProperties(); | 461 || !HasFastProperties(); |
| 442 } | 462 } |
| 443 | 463 |
| 444 | 464 |
| 445 Object* Object::GetProperty(Object* receiver, | 465 Object* Object::GetProperty(Object* receiver, |
| 446 LookupResult* result, | 466 LookupResult* result, |
| 447 String* name, | 467 String* name, |
| 448 PropertyAttributes* attributes) { | 468 PropertyAttributes* attributes) { |
| 449 // Make sure that the top context does not change when doing | 469 // Make sure that the top context does not change when doing |
| 450 // callbacks or interceptor calls. | 470 // callbacks or interceptor calls. |
| 451 AssertNoContextChange ncc; | 471 AssertNoContextChange ncc; |
| 472 Heap* heap = name->GetHeap(); |
| 452 | 473 |
| 453 // Traverse the prototype chain from the current object (this) to | 474 // Traverse the prototype chain from the current object (this) to |
| 454 // the holder and check for access rights. This avoid traversing the | 475 // the holder and check for access rights. This avoid traversing the |
| 455 // objects more than once in case of interceptors, because the | 476 // objects more than once in case of interceptors, because the |
| 456 // holder will always be the interceptor holder and the search may | 477 // holder will always be the interceptor holder and the search may |
| 457 // only continue with a current object just after the interceptor | 478 // only continue with a current object just after the interceptor |
| 458 // holder in the prototype chain. | 479 // holder in the prototype chain. |
| 459 Object* last = result->IsProperty() ? result->holder() : HEAP->null_value(); | 480 Object* last = result->IsProperty() ? result->holder() : heap->null_value(); |
| 460 for (Object* current = this; true; current = current->GetPrototype()) { | 481 for (Object* current = this; true; current = current->GetPrototype()) { |
| 461 if (current->IsAccessCheckNeeded()) { | 482 if (current->IsAccessCheckNeeded()) { |
| 462 // Check if we're allowed to read from the current object. Note | 483 // Check if we're allowed to read from the current object. Note |
| 463 // that even though we may not actually end up loading the named | 484 // that even though we may not actually end up loading the named |
| 464 // property from the current object, we still check that we have | 485 // property from the current object, we still check that we have |
| 465 // access to it. | 486 // access to it. |
| 466 JSObject* checked = JSObject::cast(current); | 487 JSObject* checked = JSObject::cast(current); |
| 467 if (!Isolate::Current()->MayNamedAccess(checked, name, v8::ACCESS_GET)) { | 488 if (!heap->isolate()->MayNamedAccess(checked, name, v8::ACCESS_GET)) { |
| 468 return checked->GetPropertyWithFailedAccessCheck(receiver, | 489 return checked->GetPropertyWithFailedAccessCheck(receiver, |
| 469 result, | 490 result, |
| 470 name, | 491 name, |
| 471 attributes); | 492 attributes); |
| 472 } | 493 } |
| 473 } | 494 } |
| 474 // Stop traversing the chain once we reach the last object in the | 495 // Stop traversing the chain once we reach the last object in the |
| 475 // chain; either the holder of the result or null in case of an | 496 // chain; either the holder of the result or null in case of an |
| 476 // absent property. | 497 // absent property. |
| 477 if (current == last) break; | 498 if (current == last) break; |
| 478 } | 499 } |
| 479 | 500 |
| 480 if (!result->IsProperty()) { | 501 if (!result->IsProperty()) { |
| 481 *attributes = ABSENT; | 502 *attributes = ABSENT; |
| 482 return HEAP->undefined_value(); | 503 return heap->undefined_value(); |
| 483 } | 504 } |
| 484 *attributes = result->GetAttributes(); | 505 *attributes = result->GetAttributes(); |
| 485 Object* value; | 506 Object* value; |
| 486 JSObject* holder = result->holder(); | 507 JSObject* holder = result->holder(); |
| 487 switch (result->type()) { | 508 switch (result->type()) { |
| 488 case NORMAL: | 509 case NORMAL: |
| 489 value = holder->GetNormalizedProperty(result); | 510 value = holder->GetNormalizedProperty(result); |
| 490 ASSERT(!value->IsTheHole() || result->IsReadOnly()); | 511 ASSERT(!value->IsTheHole() || result->IsReadOnly()); |
| 491 return value->IsTheHole() ? HEAP->undefined_value() : value; | 512 return value->IsTheHole() ? heap->undefined_value() : value; |
| 492 case FIELD: | 513 case FIELD: |
| 493 value = holder->FastPropertyAt(result->GetFieldIndex()); | 514 value = holder->FastPropertyAt(result->GetFieldIndex()); |
| 494 ASSERT(!value->IsTheHole() || result->IsReadOnly()); | 515 ASSERT(!value->IsTheHole() || result->IsReadOnly()); |
| 495 return value->IsTheHole() ? HEAP->undefined_value() : value; | 516 return value->IsTheHole() ? heap->undefined_value() : value; |
| 496 case CONSTANT_FUNCTION: | 517 case CONSTANT_FUNCTION: |
| 497 return result->GetConstantFunction(); | 518 return result->GetConstantFunction(); |
| 498 case CALLBACKS: | 519 case CALLBACKS: |
| 499 return GetPropertyWithCallback(receiver, | 520 return GetPropertyWithCallback(receiver, |
| 500 result->GetCallbackObject(), | 521 result->GetCallbackObject(), |
| 501 name, | 522 name, |
| 502 holder); | 523 holder); |
| 503 case INTERCEPTOR: { | 524 case INTERCEPTOR: { |
| 504 JSObject* recvr = JSObject::cast(receiver); | 525 JSObject* recvr = JSObject::cast(receiver); |
| 505 return holder->GetPropertyWithInterceptor(recvr, name, attributes); | 526 return holder->GetPropertyWithInterceptor(recvr, name, attributes); |
| 506 } | 527 } |
| 507 default: | 528 default: |
| 508 UNREACHABLE(); | 529 UNREACHABLE(); |
| 509 return NULL; | 530 return NULL; |
| 510 } | 531 } |
| 511 } | 532 } |
| 512 | 533 |
| 513 | 534 |
| 514 Object* Object::GetElementWithReceiver(Object* receiver, uint32_t index) { | 535 Object* Object::GetElementWithReceiver(Object* receiver, uint32_t index) { |
| 515 // Non-JS objects do not have integer indexed properties. | 536 // Non-JS objects do not have integer indexed properties. |
| 516 if (!IsJSObject()) return HEAP->undefined_value(); | 537 if (!IsJSObject()) return Isolate::Current()->heap()->undefined_value(); |
| 517 return JSObject::cast(this)->GetElementWithReceiver(JSObject::cast(receiver), | 538 return JSObject::cast(this)->GetElementWithReceiver(JSObject::cast(receiver), |
| 518 index); | 539 index); |
| 519 } | 540 } |
| 520 | 541 |
| 521 | 542 |
| 522 Object* Object::GetPrototype() { | 543 Object* Object::GetPrototype() { |
| 523 // The object is either a number, a string, a boolean, or a real JS object. | 544 // The object is either a number, a string, a boolean, or a real JS object. |
| 524 if (IsJSObject()) return JSObject::cast(this)->map()->prototype(); | 545 if (IsJSObject()) return JSObject::cast(this)->map()->prototype(); |
| 525 Context* context = Isolate::Current()->context()->global_context(); | 546 Heap* heap = Isolate::Current()->heap(); |
| 547 Context* context = heap->isolate()->context()->global_context(); |
| 526 | 548 |
| 527 if (IsNumber()) return context->number_function()->instance_prototype(); | 549 if (IsNumber()) return context->number_function()->instance_prototype(); |
| 528 if (IsString()) return context->string_function()->instance_prototype(); | 550 if (IsString()) return context->string_function()->instance_prototype(); |
| 529 if (IsBoolean()) { | 551 if (IsBoolean()) { |
| 530 return context->boolean_function()->instance_prototype(); | 552 return context->boolean_function()->instance_prototype(); |
| 531 } else { | 553 } else { |
| 532 return HEAP->null_value(); | 554 return heap->null_value(); |
| 533 } | 555 } |
| 534 } | 556 } |
| 535 | 557 |
| 536 | 558 |
| 537 void Object::ShortPrint() { | 559 void Object::ShortPrint() { |
| 538 HeapStringAllocator allocator; | 560 HeapStringAllocator allocator; |
| 539 StringStream accumulator(&allocator); | 561 StringStream accumulator(&allocator); |
| 540 ShortPrint(&accumulator); | 562 ShortPrint(&accumulator); |
| 541 accumulator.OutputToStdOut(); | 563 accumulator.OutputToStdOut(); |
| 542 } | 564 } |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 621 | 643 |
| 622 Object* String::SlowTryFlatten(PretenureFlag pretenure) { | 644 Object* String::SlowTryFlatten(PretenureFlag pretenure) { |
| 623 #ifdef DEBUG | 645 #ifdef DEBUG |
| 624 // Do not attempt to flatten in debug mode when allocation is not | 646 // Do not attempt to flatten in debug mode when allocation is not |
| 625 // allowed. This is to avoid an assertion failure when allocating. | 647 // allowed. This is to avoid an assertion failure when allocating. |
| 626 // Flattening strings is the only case where we always allow | 648 // Flattening strings is the only case where we always allow |
| 627 // allocation because no GC is performed if the allocation fails. | 649 // allocation because no GC is performed if the allocation fails. |
| 628 if (!HEAP->IsAllocationAllowed()) return this; | 650 if (!HEAP->IsAllocationAllowed()) return this; |
| 629 #endif | 651 #endif |
| 630 | 652 |
| 653 Heap* heap = GetHeap(); |
| 631 switch (StringShape(this).representation_tag()) { | 654 switch (StringShape(this).representation_tag()) { |
| 632 case kConsStringTag: { | 655 case kConsStringTag: { |
| 633 ConsString* cs = ConsString::cast(this); | 656 ConsString* cs = ConsString::cast(this); |
| 634 if (cs->second()->length() == 0) { | 657 if (cs->second()->length() == 0) { |
| 635 return cs->first(); | 658 return cs->first(); |
| 636 } | 659 } |
| 637 // There's little point in putting the flat string in new space if the | 660 // There's little point in putting the flat string in new space if the |
| 638 // cons string is in old space. It can never get GCed until there is | 661 // cons string is in old space. It can never get GCed until there is |
| 639 // an old space GC. | 662 // an old space GC. |
| 640 PretenureFlag tenure = HEAP->InNewSpace(this) ? pretenure : TENURED; | 663 PretenureFlag tenure = heap->InNewSpace(this) ? pretenure : TENURED; |
| 641 int len = length(); | 664 int len = length(); |
| 642 Object* object; | 665 Object* object; |
| 643 String* result; | 666 String* result; |
| 644 if (IsAsciiRepresentation()) { | 667 if (IsAsciiRepresentation()) { |
| 645 object = HEAP->AllocateRawAsciiString(len, tenure); | 668 object = heap->AllocateRawAsciiString(len, tenure); |
| 646 if (object->IsFailure()) return object; | 669 if (object->IsFailure()) return object; |
| 647 result = String::cast(object); | 670 result = String::cast(object); |
| 648 String* first = cs->first(); | 671 String* first = cs->first(); |
| 649 int first_length = first->length(); | 672 int first_length = first->length(); |
| 650 char* dest = SeqAsciiString::cast(result)->GetChars(); | 673 char* dest = SeqAsciiString::cast(result)->GetChars(); |
| 651 WriteToFlat(first, dest, 0, first_length); | 674 WriteToFlat(first, dest, 0, first_length); |
| 652 String* second = cs->second(); | 675 String* second = cs->second(); |
| 653 WriteToFlat(second, | 676 WriteToFlat(second, |
| 654 dest + first_length, | 677 dest + first_length, |
| 655 0, | 678 0, |
| 656 len - first_length); | 679 len - first_length); |
| 657 } else { | 680 } else { |
| 658 object = HEAP->AllocateRawTwoByteString(len, tenure); | 681 object = heap->AllocateRawTwoByteString(len, tenure); |
| 659 if (object->IsFailure()) return object; | 682 if (object->IsFailure()) return object; |
| 660 result = String::cast(object); | 683 result = String::cast(object); |
| 661 uc16* dest = SeqTwoByteString::cast(result)->GetChars(); | 684 uc16* dest = SeqTwoByteString::cast(result)->GetChars(); |
| 662 String* first = cs->first(); | 685 String* first = cs->first(); |
| 663 int first_length = first->length(); | 686 int first_length = first->length(); |
| 664 WriteToFlat(first, dest, 0, first_length); | 687 WriteToFlat(first, dest, 0, first_length); |
| 665 String* second = cs->second(); | 688 String* second = cs->second(); |
| 666 WriteToFlat(second, | 689 WriteToFlat(second, |
| 667 dest + first_length, | 690 dest + first_length, |
| 668 0, | 691 0, |
| 669 len - first_length); | 692 len - first_length); |
| 670 } | 693 } |
| 671 cs->set_first(result); | 694 cs->set_first(result); |
| 672 cs->set_second(HEAP->empty_string()); | 695 cs->set_second(heap->empty_string()); |
| 673 return result; | 696 return result; |
| 674 } | 697 } |
| 675 default: | 698 default: |
| 676 return this; | 699 return this; |
| 677 } | 700 } |
| 678 } | 701 } |
| 679 | 702 |
| 680 | 703 |
| 681 bool String::MakeExternal(v8::String::ExternalStringResource* resource) { | 704 bool String::MakeExternal(v8::String::ExternalStringResource* resource) { |
| 682 // Externalizing twice leaks the external resource, so it's | 705 // Externalizing twice leaks the external resource, so it's |
| 683 // prohibited by the API. | 706 // prohibited by the API. |
| 684 ASSERT(!this->IsExternalString()); | 707 ASSERT(!this->IsExternalString()); |
| 685 #ifdef DEBUG | 708 #ifdef DEBUG |
| 686 if (FLAG_enable_slow_asserts) { | 709 if (FLAG_enable_slow_asserts) { |
| 687 // Assert that the resource and the string are equivalent. | 710 // Assert that the resource and the string are equivalent. |
| 688 ASSERT(static_cast<size_t>(this->length()) == resource->length()); | 711 ASSERT(static_cast<size_t>(this->length()) == resource->length()); |
| 689 ScopedVector<uc16> smart_chars(this->length()); | 712 ScopedVector<uc16> smart_chars(this->length()); |
| 690 String::WriteToFlat(this, smart_chars.start(), 0, this->length()); | 713 String::WriteToFlat(this, smart_chars.start(), 0, this->length()); |
| 691 ASSERT(memcmp(smart_chars.start(), | 714 ASSERT(memcmp(smart_chars.start(), |
| 692 resource->data(), | 715 resource->data(), |
| 693 resource->length() * sizeof(smart_chars[0])) == 0); | 716 resource->length() * sizeof(smart_chars[0])) == 0); |
| 694 } | 717 } |
| 695 #endif // DEBUG | 718 #endif // DEBUG |
| 696 | 719 Heap* heap = GetHeap(); |
| 697 int size = this->Size(); // Byte size of the original string. | 720 int size = this->Size(); // Byte size of the original string. |
| 698 if (size < ExternalString::kSize) { | 721 if (size < ExternalString::kSize) { |
| 699 // The string is too small to fit an external String in its place. This can | 722 // The string is too small to fit an external String in its place. This can |
| 700 // only happen for zero length strings. | 723 // only happen for zero length strings. |
| 701 return false; | 724 return false; |
| 702 } | 725 } |
| 703 ASSERT(size >= ExternalString::kSize); | 726 ASSERT(size >= ExternalString::kSize); |
| 704 bool is_ascii = this->IsAsciiRepresentation(); | 727 bool is_ascii = this->IsAsciiRepresentation(); |
| 705 bool is_symbol = this->IsSymbol(); | 728 bool is_symbol = this->IsSymbol(); |
| 706 int length = this->length(); | 729 int length = this->length(); |
| 707 int hash_field = this->hash_field(); | 730 int hash_field = this->hash_field(); |
| 708 | 731 |
| 709 // Morph the object to an external string by adjusting the map and | 732 // Morph the object to an external string by adjusting the map and |
| 710 // reinitializing the fields. | 733 // reinitializing the fields. |
| 711 this->set_map(is_ascii ? | 734 this->set_map(is_ascii ? |
| 712 HEAP->external_string_with_ascii_data_map() : | 735 heap->external_string_with_ascii_data_map() : |
| 713 HEAP->external_string_map()); | 736 heap->external_string_map()); |
| 714 ExternalTwoByteString* self = ExternalTwoByteString::cast(this); | 737 ExternalTwoByteString* self = ExternalTwoByteString::cast(this); |
| 715 self->set_length(length); | 738 self->set_length(length); |
| 716 self->set_hash_field(hash_field); | 739 self->set_hash_field(hash_field); |
| 717 self->set_resource(resource); | 740 self->set_resource(resource); |
| 718 // Additionally make the object into an external symbol if the original string | 741 // Additionally make the object into an external symbol if the original string |
| 719 // was a symbol to start with. | 742 // was a symbol to start with. |
| 720 if (is_symbol) { | 743 if (is_symbol) { |
| 721 self->Hash(); // Force regeneration of the hash value. | 744 self->Hash(); // Force regeneration of the hash value. |
| 722 // Now morph this external string into a external symbol. | 745 // Now morph this external string into a external symbol. |
| 723 this->set_map(is_ascii ? | 746 this->set_map(is_ascii ? |
| 724 HEAP->external_symbol_with_ascii_data_map() : | 747 heap->external_symbol_with_ascii_data_map() : |
| 725 HEAP->external_symbol_map()); | 748 heap->external_symbol_map()); |
| 726 } | 749 } |
| 727 | 750 |
| 728 // Fill the remainder of the string with dead wood. | 751 // Fill the remainder of the string with dead wood. |
| 729 int new_size = this->Size(); // Byte size of the external String object. | 752 int new_size = this->Size(); // Byte size of the external String object. |
| 730 HEAP->CreateFillerObjectAt(this->address() + new_size, size - new_size); | 753 heap->CreateFillerObjectAt(this->address() + new_size, size - new_size); |
| 731 return true; | 754 return true; |
| 732 } | 755 } |
| 733 | 756 |
| 734 | 757 |
| 735 bool String::MakeExternal(v8::String::ExternalAsciiStringResource* resource) { | 758 bool String::MakeExternal(v8::String::ExternalAsciiStringResource* resource) { |
| 736 #ifdef DEBUG | 759 #ifdef DEBUG |
| 737 if (FLAG_enable_slow_asserts) { | 760 if (FLAG_enable_slow_asserts) { |
| 738 // Assert that the resource and the string are equivalent. | 761 // Assert that the resource and the string are equivalent. |
| 739 ASSERT(static_cast<size_t>(this->length()) == resource->length()); | 762 ASSERT(static_cast<size_t>(this->length()) == resource->length()); |
| 740 ScopedVector<char> smart_chars(this->length()); | 763 ScopedVector<char> smart_chars(this->length()); |
| 741 String::WriteToFlat(this, smart_chars.start(), 0, this->length()); | 764 String::WriteToFlat(this, smart_chars.start(), 0, this->length()); |
| 742 ASSERT(memcmp(smart_chars.start(), | 765 ASSERT(memcmp(smart_chars.start(), |
| 743 resource->data(), | 766 resource->data(), |
| 744 resource->length() * sizeof(smart_chars[0])) == 0); | 767 resource->length() * sizeof(smart_chars[0])) == 0); |
| 745 } | 768 } |
| 746 #endif // DEBUG | 769 #endif // DEBUG |
| 747 | 770 Heap* heap = GetHeap(); |
| 748 int size = this->Size(); // Byte size of the original string. | 771 int size = this->Size(); // Byte size of the original string. |
| 749 if (size < ExternalString::kSize) { | 772 if (size < ExternalString::kSize) { |
| 750 // The string is too small to fit an external String in its place. This can | 773 // The string is too small to fit an external String in its place. This can |
| 751 // only happen for zero length strings. | 774 // only happen for zero length strings. |
| 752 return false; | 775 return false; |
| 753 } | 776 } |
| 754 ASSERT(size >= ExternalString::kSize); | 777 ASSERT(size >= ExternalString::kSize); |
| 755 bool is_symbol = this->IsSymbol(); | 778 bool is_symbol = this->IsSymbol(); |
| 756 int length = this->length(); | 779 int length = this->length(); |
| 757 int hash_field = this->hash_field(); | 780 int hash_field = this->hash_field(); |
| 758 | 781 |
| 759 // Morph the object to an external string by adjusting the map and | 782 // Morph the object to an external string by adjusting the map and |
| 760 // reinitializing the fields. | 783 // reinitializing the fields. |
| 761 this->set_map(HEAP->external_ascii_string_map()); | 784 this->set_map(heap->external_ascii_string_map()); |
| 762 ExternalAsciiString* self = ExternalAsciiString::cast(this); | 785 ExternalAsciiString* self = ExternalAsciiString::cast(this); |
| 763 self->set_length(length); | 786 self->set_length(length); |
| 764 self->set_hash_field(hash_field); | 787 self->set_hash_field(hash_field); |
| 765 self->set_resource(resource); | 788 self->set_resource(resource); |
| 766 // Additionally make the object into an external symbol if the original string | 789 // Additionally make the object into an external symbol if the original string |
| 767 // was a symbol to start with. | 790 // was a symbol to start with. |
| 768 if (is_symbol) { | 791 if (is_symbol) { |
| 769 self->Hash(); // Force regeneration of the hash value. | 792 self->Hash(); // Force regeneration of the hash value. |
| 770 // Now morph this external string into a external symbol. | 793 // Now morph this external string into a external symbol. |
| 771 this->set_map(HEAP->external_ascii_symbol_map()); | 794 this->set_map(heap->external_ascii_symbol_map()); |
| 772 } | 795 } |
| 773 | 796 |
| 774 // Fill the remainder of the string with dead wood. | 797 // Fill the remainder of the string with dead wood. |
| 775 int new_size = this->Size(); // Byte size of the external String object. | 798 int new_size = this->Size(); // Byte size of the external String object. |
| 776 HEAP->CreateFillerObjectAt(this->address() + new_size, size - new_size); | 799 heap->CreateFillerObjectAt(this->address() + new_size, size - new_size); |
| 777 return true; | 800 return true; |
| 778 } | 801 } |
| 779 | 802 |
| 780 | 803 |
| 781 void String::StringShortPrint(StringStream* accumulator) { | 804 void String::StringShortPrint(StringStream* accumulator) { |
| 782 int len = length(); | 805 int len = length(); |
| 783 if (len > kMaxShortPrintLength) { | 806 if (len > kMaxShortPrintLength) { |
| 784 accumulator->Add("<Very long string[%u]>", len); | 807 accumulator->Add("<Very long string[%u]>", len); |
| 785 return; | 808 return; |
| 786 } | 809 } |
| (...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 865 } | 888 } |
| 866 } | 889 } |
| 867 if (!printed) { | 890 if (!printed) { |
| 868 accumulator->Add("<JS Function>"); | 891 accumulator->Add("<JS Function>"); |
| 869 } | 892 } |
| 870 break; | 893 break; |
| 871 } | 894 } |
| 872 // All other JSObjects are rather similar to each other (JSObject, | 895 // All other JSObjects are rather similar to each other (JSObject, |
| 873 // JSGlobalProxy, JSGlobalObject, JSUndetectableObject, JSValue). | 896 // JSGlobalProxy, JSGlobalObject, JSUndetectableObject, JSValue). |
| 874 default: { | 897 default: { |
| 898 Heap* heap = GetHeap(); |
| 875 Object* constructor = map()->constructor(); | 899 Object* constructor = map()->constructor(); |
| 876 bool printed = false; | 900 bool printed = false; |
| 877 if (constructor->IsHeapObject() && | 901 if (constructor->IsHeapObject() && |
| 878 !HEAP->Contains(HeapObject::cast(constructor))) { | 902 !heap->Contains(HeapObject::cast(constructor))) { |
| 879 accumulator->Add("!!!INVALID CONSTRUCTOR!!!"); | 903 accumulator->Add("!!!INVALID CONSTRUCTOR!!!"); |
| 880 } else { | 904 } else { |
| 881 bool global_object = IsJSGlobalProxy(); | 905 bool global_object = IsJSGlobalProxy(); |
| 882 if (constructor->IsJSFunction()) { | 906 if (constructor->IsJSFunction()) { |
| 883 if (!HEAP->Contains(JSFunction::cast(constructor)->shared())) { | 907 if (!heap->Contains(JSFunction::cast(constructor)->shared())) { |
| 884 accumulator->Add("!!!INVALID SHARED ON CONSTRUCTOR!!!"); | 908 accumulator->Add("!!!INVALID SHARED ON CONSTRUCTOR!!!"); |
| 885 } else { | 909 } else { |
| 886 Object* constructor_name = | 910 Object* constructor_name = |
| 887 JSFunction::cast(constructor)->shared()->name(); | 911 JSFunction::cast(constructor)->shared()->name(); |
| 888 if (constructor_name->IsString()) { | 912 if (constructor_name->IsString()) { |
| 889 String* str = String::cast(constructor_name); | 913 String* str = String::cast(constructor_name); |
| 890 if (str->length() > 0) { | 914 if (str->length() > 0) { |
| 891 bool vowel = AnWord(str); | 915 bool vowel = AnWord(str); |
| 892 accumulator->Add("<%sa%s ", | 916 accumulator->Add("<%sa%s ", |
| 893 global_object ? "Global Object: " : "", | 917 global_object ? "Global Object: " : "", |
| (...skipping 15 matching lines...) Expand all Loading... |
| 909 } | 933 } |
| 910 accumulator->Put('>'); | 934 accumulator->Put('>'); |
| 911 break; | 935 break; |
| 912 } | 936 } |
| 913 } | 937 } |
| 914 } | 938 } |
| 915 | 939 |
| 916 | 940 |
| 917 void HeapObject::HeapObjectShortPrint(StringStream* accumulator) { | 941 void HeapObject::HeapObjectShortPrint(StringStream* accumulator) { |
| 918 // if (!Heap::InNewSpace(this)) PrintF("*", this); | 942 // if (!Heap::InNewSpace(this)) PrintF("*", this); |
| 919 if (!HEAP->Contains(this)) { | 943 Heap* heap = GetHeap(); |
| 944 if (!heap->Contains(this)) { |
| 920 accumulator->Add("!!!INVALID POINTER!!!"); | 945 accumulator->Add("!!!INVALID POINTER!!!"); |
| 921 return; | 946 return; |
| 922 } | 947 } |
| 923 if (!HEAP->Contains(map())) { | 948 if (!heap->Contains(map())) { |
| 924 accumulator->Add("!!!INVALID MAP!!!"); | 949 accumulator->Add("!!!INVALID MAP!!!"); |
| 925 return; | 950 return; |
| 926 } | 951 } |
| 927 | 952 |
| 928 accumulator->Add("%p ", this); | 953 accumulator->Add("%p ", this); |
| 929 | 954 |
| 930 if (IsString()) { | 955 if (IsString()) { |
| 931 String::cast(this)->StringShortPrint(accumulator); | 956 String::cast(this)->StringShortPrint(accumulator); |
| 932 return; | 957 return; |
| 933 } | 958 } |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1152 | 1177 |
| 1153 void HeapObject::IterateStructBody(int object_size, ObjectVisitor* v) { | 1178 void HeapObject::IterateStructBody(int object_size, ObjectVisitor* v) { |
| 1154 IteratePointers(v, HeapObject::kHeaderSize, object_size); | 1179 IteratePointers(v, HeapObject::kHeaderSize, object_size); |
| 1155 } | 1180 } |
| 1156 | 1181 |
| 1157 | 1182 |
| 1158 Object* HeapNumber::HeapNumberToBoolean() { | 1183 Object* HeapNumber::HeapNumberToBoolean() { |
| 1159 // NaN, +0, and -0 should return the false object | 1184 // NaN, +0, and -0 should return the false object |
| 1160 switch (fpclassify(value())) { | 1185 switch (fpclassify(value())) { |
| 1161 case FP_NAN: // fall through | 1186 case FP_NAN: // fall through |
| 1162 case FP_ZERO: return HEAP->false_value(); | 1187 case FP_ZERO: return GetHeap()->false_value(); |
| 1163 default: return HEAP->true_value(); | 1188 default: return GetHeap()->true_value(); |
| 1164 } | 1189 } |
| 1165 } | 1190 } |
| 1166 | 1191 |
| 1167 | 1192 |
| 1168 void HeapNumber::HeapNumberPrint() { | 1193 void HeapNumber::HeapNumberPrint() { |
| 1169 PrintF("%.16g", Number()); | 1194 PrintF("%.16g", Number()); |
| 1170 } | 1195 } |
| 1171 | 1196 |
| 1172 | 1197 |
| 1173 void HeapNumber::HeapNumberPrint(StringStream* accumulator) { | 1198 void HeapNumber::HeapNumberPrint(StringStream* accumulator) { |
| 1174 // The Windows version of vsnprintf can allocate when printing a %g string | 1199 // The Windows version of vsnprintf can allocate when printing a %g string |
| 1175 // into a buffer that may not be big enough. We don't want random memory | 1200 // into a buffer that may not be big enough. We don't want random memory |
| 1176 // allocation when producing post-crash stack traces, so we print into a | 1201 // allocation when producing post-crash stack traces, so we print into a |
| 1177 // buffer that is plenty big enough for any floating point number, then | 1202 // buffer that is plenty big enough for any floating point number, then |
| 1178 // print that using vsnprintf (which may truncate but never allocate if | 1203 // print that using vsnprintf (which may truncate but never allocate if |
| 1179 // there is no more space in the buffer). | 1204 // there is no more space in the buffer). |
| 1180 EmbeddedVector<char, 100> buffer; | 1205 EmbeddedVector<char, 100> buffer; |
| 1181 OS::SNPrintF(buffer, "%.16g", Number()); | 1206 OS::SNPrintF(buffer, "%.16g", Number()); |
| 1182 accumulator->Add("%s", buffer.start()); | 1207 accumulator->Add("%s", buffer.start()); |
| 1183 } | 1208 } |
| 1184 | 1209 |
| 1185 | 1210 |
| 1186 String* JSObject::class_name() { | 1211 String* JSObject::class_name() { |
| 1187 if (IsJSFunction()) { | 1212 if (IsJSFunction()) { |
| 1188 return HEAP->function_class_symbol(); | 1213 return GetHeap()->function_class_symbol(); |
| 1189 } | 1214 } |
| 1190 if (map()->constructor()->IsJSFunction()) { | 1215 if (map()->constructor()->IsJSFunction()) { |
| 1191 JSFunction* constructor = JSFunction::cast(map()->constructor()); | 1216 JSFunction* constructor = JSFunction::cast(map()->constructor()); |
| 1192 return String::cast(constructor->shared()->instance_class_name()); | 1217 return String::cast(constructor->shared()->instance_class_name()); |
| 1193 } | 1218 } |
| 1194 // If the constructor is not present, return "Object". | 1219 // If the constructor is not present, return "Object". |
| 1195 return HEAP->Object_symbol(); | 1220 return GetHeap()->Object_symbol(); |
| 1196 } | 1221 } |
| 1197 | 1222 |
| 1198 | 1223 |
| 1199 String* JSObject::constructor_name() { | 1224 String* JSObject::constructor_name() { |
| 1200 if (IsJSFunction()) { | 1225 if (IsJSFunction()) { |
| 1201 return HEAP->closure_symbol(); | 1226 return GetHeap()->closure_symbol(); |
| 1202 } | 1227 } |
| 1203 if (map()->constructor()->IsJSFunction()) { | 1228 if (map()->constructor()->IsJSFunction()) { |
| 1204 JSFunction* constructor = JSFunction::cast(map()->constructor()); | 1229 JSFunction* constructor = JSFunction::cast(map()->constructor()); |
| 1205 String* name = String::cast(constructor->shared()->name()); | 1230 String* name = String::cast(constructor->shared()->name()); |
| 1206 return name->length() > 0 ? name : constructor->shared()->inferred_name(); | 1231 return name->length() > 0 ? name : constructor->shared()->inferred_name(); |
| 1207 } | 1232 } |
| 1208 // If the constructor is not present, return "Object". | 1233 // If the constructor is not present, return "Object". |
| 1209 return HEAP->Object_symbol(); | 1234 return GetHeap()->Object_symbol(); |
| 1210 } | 1235 } |
| 1211 | 1236 |
| 1212 | 1237 |
| 1213 void JSObject::JSObjectIterateBody(int object_size, ObjectVisitor* v) { | 1238 void JSObject::JSObjectIterateBody(int object_size, ObjectVisitor* v) { |
| 1214 // Iterate over all fields in the body. Assumes all are Object*. | 1239 // Iterate over all fields in the body. Assumes all are Object*. |
| 1215 IteratePointers(v, kPropertiesOffset, object_size); | 1240 IteratePointers(v, kPropertiesOffset, object_size); |
| 1216 } | 1241 } |
| 1217 | 1242 |
| 1218 | 1243 |
| 1219 Object* JSObject::AddFastPropertyUsingMap(Map* new_map, | 1244 Object* JSObject::AddFastPropertyUsingMap(Map* new_map, |
| (...skipping 11 matching lines...) Expand all Loading... |
| 1231 set_map(new_map); | 1256 set_map(new_map); |
| 1232 return FastPropertyAtPut(index, value); | 1257 return FastPropertyAtPut(index, value); |
| 1233 } | 1258 } |
| 1234 | 1259 |
| 1235 | 1260 |
| 1236 Object* JSObject::AddFastProperty(String* name, | 1261 Object* JSObject::AddFastProperty(String* name, |
| 1237 Object* value, | 1262 Object* value, |
| 1238 PropertyAttributes attributes) { | 1263 PropertyAttributes attributes) { |
| 1239 // Normalize the object if the name is an actual string (not the | 1264 // Normalize the object if the name is an actual string (not the |
| 1240 // hidden symbols) and is not a real identifier. | 1265 // hidden symbols) and is not a real identifier. |
| 1266 Isolate* isolate = GetHeap()->isolate(); |
| 1241 StringInputBuffer buffer(name); | 1267 StringInputBuffer buffer(name); |
| 1242 Isolate* isolate = Isolate::Current(); | |
| 1243 if (!isolate->scanner_character_classes()->IsIdentifier(&buffer) && | 1268 if (!isolate->scanner_character_classes()->IsIdentifier(&buffer) && |
| 1244 name != isolate->heap()->hidden_symbol()) { | 1269 name != isolate->heap()->hidden_symbol()) { |
| 1245 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 1270 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
| 1246 if (obj->IsFailure()) return obj; | 1271 if (obj->IsFailure()) return obj; |
| 1247 return AddSlowProperty(name, value, attributes); | 1272 return AddSlowProperty(name, value, attributes); |
| 1248 } | 1273 } |
| 1249 | 1274 |
| 1250 DescriptorArray* old_descriptors = map()->instance_descriptors(); | 1275 DescriptorArray* old_descriptors = map()->instance_descriptors(); |
| 1251 // Compute the new index for new field. | 1276 // Compute the new index for new field. |
| 1252 int index = map()->NextFreePropertyIndex(); | 1277 int index = map()->NextFreePropertyIndex(); |
| 1253 | 1278 |
| 1254 // Allocate new instance descriptors with (name, index) added | 1279 // Allocate new instance descriptors with (name, index) added |
| 1255 FieldDescriptor new_field(name, index, attributes); | 1280 FieldDescriptor new_field(name, index, attributes); |
| 1256 Object* new_descriptors = | 1281 Object* new_descriptors = |
| 1257 old_descriptors->CopyInsert(&new_field, REMOVE_TRANSITIONS); | 1282 old_descriptors->CopyInsert(&new_field, REMOVE_TRANSITIONS); |
| 1258 if (new_descriptors->IsFailure()) return new_descriptors; | 1283 if (new_descriptors->IsFailure()) return new_descriptors; |
| 1259 | 1284 |
| 1260 // 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 |
| 1261 // 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. |
| 1262 bool allow_map_transition = | 1287 bool allow_map_transition = |
| 1263 !old_descriptors->Contains(name) && | 1288 !old_descriptors->Contains(name) && |
| 1264 (Isolate::Current()->context()->global_context()->object_function()-> | 1289 (isolate->context()->global_context()->object_function()-> |
| 1265 map() != map()); | 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 = map()->CopyDropDescriptors(); | 1296 Object* r = map()->CopyDropDescriptors(); |
| 1272 if (r->IsFailure()) return r; | 1297 if (r->IsFailure()) return r; |
| 1273 Map* new_map = Map::cast(r); | 1298 Map* new_map = Map::cast(r); |
| 1274 if (allow_map_transition) { | 1299 if (allow_map_transition) { |
| (...skipping 26 matching lines...) Expand all Loading... |
| 1301 set_map(new_map); | 1326 set_map(new_map); |
| 1302 return FastPropertyAtPut(index, value); | 1327 return FastPropertyAtPut(index, value); |
| 1303 } | 1328 } |
| 1304 | 1329 |
| 1305 | 1330 |
| 1306 Object* JSObject::AddConstantFunctionProperty(String* name, | 1331 Object* JSObject::AddConstantFunctionProperty(String* name, |
| 1307 JSFunction* function, | 1332 JSFunction* function, |
| 1308 PropertyAttributes attributes) { | 1333 PropertyAttributes attributes) { |
| 1309 ASSERT(!HEAP->InNewSpace(function)); | 1334 ASSERT(!HEAP->InNewSpace(function)); |
| 1310 | 1335 |
| 1336 Heap* heap = GetHeap(); |
| 1337 |
| 1311 // Allocate new instance descriptors with (name, function) added | 1338 // Allocate new instance descriptors with (name, function) added |
| 1312 ConstantFunctionDescriptor d(name, function, attributes); | 1339 ConstantFunctionDescriptor d(name, function, attributes); |
| 1313 Object* new_descriptors = | 1340 Object* new_descriptors = |
| 1314 map()->instance_descriptors()->CopyInsert(&d, REMOVE_TRANSITIONS); | 1341 map()->instance_descriptors()->CopyInsert(&d, REMOVE_TRANSITIONS); |
| 1315 if (new_descriptors->IsFailure()) return new_descriptors; | 1342 if (new_descriptors->IsFailure()) return new_descriptors; |
| 1316 | 1343 |
| 1317 // Allocate a new map for the object. | 1344 // Allocate a new map for the object. |
| 1318 Object* new_map = map()->CopyDropDescriptors(); | 1345 Object* new_map = map()->CopyDropDescriptors(); |
| 1319 if (new_map->IsFailure()) return new_map; | 1346 if (new_map->IsFailure()) return new_map; |
| 1320 | 1347 |
| 1321 DescriptorArray* descriptors = DescriptorArray::cast(new_descriptors); | 1348 DescriptorArray* descriptors = DescriptorArray::cast(new_descriptors); |
| 1322 Map::cast(new_map)->set_instance_descriptors(descriptors); | 1349 Map::cast(new_map)->set_instance_descriptors(descriptors); |
| 1323 Map* old_map = map(); | 1350 Map* old_map = map(); |
| 1324 set_map(Map::cast(new_map)); | 1351 set_map(Map::cast(new_map)); |
| 1325 | 1352 |
| 1326 // If the old map is the global object map (from new Object()), | 1353 // If the old map is the global object map (from new Object()), |
| 1327 // then transitions are not added to it, so we are done. | 1354 // then transitions are not added to it, so we are done. |
| 1328 if (old_map == Isolate::Current()->context()->global_context()-> | 1355 if (old_map == heap->isolate()->context()->global_context()-> |
| 1329 object_function()->map()) { | 1356 object_function()->map()) { |
| 1330 return function; | 1357 return function; |
| 1331 } | 1358 } |
| 1332 | 1359 |
| 1333 // Do not add CONSTANT_TRANSITIONS to global objects | 1360 // Do not add CONSTANT_TRANSITIONS to global objects |
| 1334 if (IsGlobalObject()) { | 1361 if (IsGlobalObject()) { |
| 1335 return function; | 1362 return function; |
| 1336 } | 1363 } |
| 1337 | 1364 |
| 1338 // Add a CONSTANT_TRANSITION descriptor to the old map, | 1365 // Add a CONSTANT_TRANSITION descriptor to the old map, |
| (...skipping 13 matching lines...) Expand all Loading... |
| 1352 | 1379 |
| 1353 return function; | 1380 return function; |
| 1354 } | 1381 } |
| 1355 | 1382 |
| 1356 | 1383 |
| 1357 // Add property in slow mode | 1384 // Add property in slow mode |
| 1358 Object* JSObject::AddSlowProperty(String* name, | 1385 Object* JSObject::AddSlowProperty(String* name, |
| 1359 Object* value, | 1386 Object* value, |
| 1360 PropertyAttributes attributes) { | 1387 PropertyAttributes attributes) { |
| 1361 ASSERT(!HasFastProperties()); | 1388 ASSERT(!HasFastProperties()); |
| 1389 Heap* heap = GetHeap(); |
| 1362 StringDictionary* dict = property_dictionary(); | 1390 StringDictionary* dict = property_dictionary(); |
| 1363 Object* store_value = value; | 1391 Object* store_value = value; |
| 1364 if (IsGlobalObject()) { | 1392 if (IsGlobalObject()) { |
| 1365 // In case name is an orphaned property reuse the cell. | 1393 // In case name is an orphaned property reuse the cell. |
| 1366 int entry = dict->FindEntry(name); | 1394 int entry = dict->FindEntry(name); |
| 1367 if (entry != StringDictionary::kNotFound) { | 1395 if (entry != StringDictionary::kNotFound) { |
| 1368 store_value = dict->ValueAt(entry); | 1396 store_value = dict->ValueAt(entry); |
| 1369 JSGlobalPropertyCell::cast(store_value)->set_value(value); | 1397 JSGlobalPropertyCell::cast(store_value)->set_value(value); |
| 1370 // Assign an enumeration index to the property and update | 1398 // Assign an enumeration index to the property and update |
| 1371 // SetNextEnumerationIndex. | 1399 // SetNextEnumerationIndex. |
| 1372 int index = dict->NextEnumerationIndex(); | 1400 int index = dict->NextEnumerationIndex(); |
| 1373 PropertyDetails details = PropertyDetails(attributes, NORMAL, index); | 1401 PropertyDetails details = PropertyDetails(attributes, NORMAL, index); |
| 1374 dict->SetNextEnumerationIndex(index + 1); | 1402 dict->SetNextEnumerationIndex(index + 1); |
| 1375 dict->SetEntry(entry, name, store_value, details); | 1403 dict->SetEntry(entry, name, store_value, details); |
| 1376 return value; | 1404 return value; |
| 1377 } | 1405 } |
| 1378 store_value = HEAP->AllocateJSGlobalPropertyCell(value); | 1406 store_value = heap->AllocateJSGlobalPropertyCell(value); |
| 1379 if (store_value->IsFailure()) return store_value; | 1407 if (store_value->IsFailure()) return store_value; |
| 1380 JSGlobalPropertyCell::cast(store_value)->set_value(value); | 1408 JSGlobalPropertyCell::cast(store_value)->set_value(value); |
| 1381 } | 1409 } |
| 1382 PropertyDetails details = PropertyDetails(attributes, NORMAL); | 1410 PropertyDetails details = PropertyDetails(attributes, NORMAL); |
| 1383 Object* result = dict->Add(name, store_value, details); | 1411 Object* result = dict->Add(name, store_value, details); |
| 1384 if (result->IsFailure()) return result; | 1412 if (result->IsFailure()) return result; |
| 1385 if (dict != result) set_properties(StringDictionary::cast(result)); | 1413 if (dict != result) set_properties(StringDictionary::cast(result)); |
| 1386 return value; | 1414 return value; |
| 1387 } | 1415 } |
| 1388 | 1416 |
| 1389 | 1417 |
| 1390 Object* JSObject::AddProperty(String* name, | 1418 Object* JSObject::AddProperty(String* name, |
| 1391 Object* value, | 1419 Object* value, |
| 1392 PropertyAttributes attributes) { | 1420 PropertyAttributes attributes) { |
| 1393 ASSERT(!IsJSGlobalProxy()); | 1421 ASSERT(!IsJSGlobalProxy()); |
| 1422 Heap* heap = GetHeap(); |
| 1394 if (!map()->is_extensible()) { | 1423 if (!map()->is_extensible()) { |
| 1395 Handle<Object> args[1] = {Handle<String>(name)}; | 1424 Handle<Object> args[1] = {Handle<String>(name)}; |
| 1396 return Isolate::Current()->Throw( | 1425 return heap->isolate()->Throw( |
| 1397 *Factory::NewTypeError("object_not_extensible", HandleVector(args, 1))); | 1426 *Factory::NewTypeError("object_not_extensible", HandleVector(args, 1))); |
| 1398 } | 1427 } |
| 1399 if (HasFastProperties()) { | 1428 if (HasFastProperties()) { |
| 1400 // Ensure the descriptor array does not get too big. | 1429 // Ensure the descriptor array does not get too big. |
| 1401 if (map()->instance_descriptors()->number_of_descriptors() < | 1430 if (map()->instance_descriptors()->number_of_descriptors() < |
| 1402 DescriptorArray::kMaxNumberOfDescriptors) { | 1431 DescriptorArray::kMaxNumberOfDescriptors) { |
| 1403 if (value->IsJSFunction() && !HEAP->InNewSpace(value)) { | 1432 if (value->IsJSFunction() && !heap->InNewSpace(value)) { |
| 1404 return AddConstantFunctionProperty(name, | 1433 return AddConstantFunctionProperty(name, |
| 1405 JSFunction::cast(value), | 1434 JSFunction::cast(value), |
| 1406 attributes); | 1435 attributes); |
| 1407 } else { | 1436 } else { |
| 1408 return AddFastProperty(name, value, attributes); | 1437 return AddFastProperty(name, value, attributes); |
| 1409 } | 1438 } |
| 1410 } else { | 1439 } else { |
| 1411 // Normalize the object to prevent very large instance descriptors. | 1440 // Normalize the object to prevent very large instance descriptors. |
| 1412 // This eliminates unwanted N^2 allocation and lookup behavior. | 1441 // This eliminates unwanted N^2 allocation and lookup behavior. |
| 1413 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 1442 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1457 PropertyAttributes attributes) { | 1486 PropertyAttributes attributes) { |
| 1458 Map* old_map = map(); | 1487 Map* old_map = map(); |
| 1459 Object* result = ConvertDescriptorToField(name, new_value, attributes); | 1488 Object* result = ConvertDescriptorToField(name, new_value, attributes); |
| 1460 if (result->IsFailure()) return result; | 1489 if (result->IsFailure()) return result; |
| 1461 // If we get to this point we have succeeded - do not return failure | 1490 // If we get to this point we have succeeded - do not return failure |
| 1462 // after this point. Later stuff is optional. | 1491 // after this point. Later stuff is optional. |
| 1463 if (!HasFastProperties()) { | 1492 if (!HasFastProperties()) { |
| 1464 return result; | 1493 return result; |
| 1465 } | 1494 } |
| 1466 // Do not add transitions to the map of "new Object()". | 1495 // Do not add transitions to the map of "new Object()". |
| 1467 if (map() == Isolate::Current()->context()->global_context()-> | 1496 if (map() == GetHeap()->isolate()->context()->global_context()-> |
| 1468 object_function()->map()) { | 1497 object_function()->map()) { |
| 1469 return result; | 1498 return result; |
| 1470 } | 1499 } |
| 1471 | 1500 |
| 1472 MapTransitionDescriptor transition(name, | 1501 MapTransitionDescriptor transition(name, |
| 1473 map(), | 1502 map(), |
| 1474 attributes); | 1503 attributes); |
| 1475 Object* new_descriptors = | 1504 Object* new_descriptors = |
| 1476 old_map->instance_descriptors()-> | 1505 old_map->instance_descriptors()-> |
| 1477 CopyInsert(&transition, KEEP_TRANSITIONS); | 1506 CopyInsert(&transition, KEEP_TRANSITIONS); |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1525 set_properties(FixedArray::cast(new_properties)); | 1554 set_properties(FixedArray::cast(new_properties)); |
| 1526 } | 1555 } |
| 1527 return FastPropertyAtPut(index, new_value); | 1556 return FastPropertyAtPut(index, new_value); |
| 1528 } | 1557 } |
| 1529 | 1558 |
| 1530 | 1559 |
| 1531 | 1560 |
| 1532 Object* JSObject::SetPropertyWithInterceptor(String* name, | 1561 Object* JSObject::SetPropertyWithInterceptor(String* name, |
| 1533 Object* value, | 1562 Object* value, |
| 1534 PropertyAttributes attributes) { | 1563 PropertyAttributes attributes) { |
| 1564 Heap* heap = GetHeap(); |
| 1535 HandleScope scope; | 1565 HandleScope scope; |
| 1536 Handle<JSObject> this_handle(this); | 1566 Handle<JSObject> this_handle(this); |
| 1537 Handle<String> name_handle(name); | 1567 Handle<String> name_handle(name); |
| 1538 Handle<Object> value_handle(value); | 1568 Handle<Object> value_handle(value); |
| 1539 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); | 1569 Handle<InterceptorInfo> interceptor(GetNamedInterceptor()); |
| 1540 if (!interceptor->setter()->IsUndefined()) { | 1570 if (!interceptor->setter()->IsUndefined()) { |
| 1541 LOG(ApiNamedPropertyAccess("interceptor-named-set", this, name)); | 1571 LOG(ApiNamedPropertyAccess("interceptor-named-set", this, name)); |
| 1542 CustomArguments args(interceptor->data(), this, this); | 1572 CustomArguments args(interceptor->data(), this, this); |
| 1543 v8::AccessorInfo info(args.end()); | 1573 v8::AccessorInfo info(args.end()); |
| 1544 v8::NamedPropertySetter setter = | 1574 v8::NamedPropertySetter setter = |
| 1545 v8::ToCData<v8::NamedPropertySetter>(interceptor->setter()); | 1575 v8::ToCData<v8::NamedPropertySetter>(interceptor->setter()); |
| 1546 v8::Handle<v8::Value> result; | 1576 v8::Handle<v8::Value> result; |
| 1547 { | 1577 { |
| 1548 // Leaving JavaScript. | 1578 // Leaving JavaScript. |
| 1549 VMState state(EXTERNAL); | 1579 VMState state(EXTERNAL); |
| 1550 Handle<Object> value_unhole(value->IsTheHole() ? | 1580 Handle<Object> value_unhole(value->IsTheHole() ? |
| 1551 HEAP->undefined_value() : | 1581 heap->undefined_value() : |
| 1552 value); | 1582 value); |
| 1553 result = setter(v8::Utils::ToLocal(name_handle), | 1583 result = setter(v8::Utils::ToLocal(name_handle), |
| 1554 v8::Utils::ToLocal(value_unhole), | 1584 v8::Utils::ToLocal(value_unhole), |
| 1555 info); | 1585 info); |
| 1556 } | 1586 } |
| 1557 RETURN_IF_SCHEDULED_EXCEPTION(); | 1587 RETURN_IF_SCHEDULED_EXCEPTION(); |
| 1558 if (!result.IsEmpty()) return *value_handle; | 1588 if (!result.IsEmpty()) return *value_handle; |
| 1559 } | 1589 } |
| 1560 Object* raw_result = this_handle->SetPropertyPostInterceptor(*name_handle, | 1590 Object* raw_result = this_handle->SetPropertyPostInterceptor(*name_handle, |
| 1561 *value_handle, | 1591 *value_handle, |
| 1562 attributes); | 1592 attributes); |
| 1563 RETURN_IF_SCHEDULED_EXCEPTION(); | 1593 RETURN_IF_SCHEDULED_EXCEPTION(); |
| 1564 return raw_result; | 1594 return raw_result; |
| 1565 } | 1595 } |
| 1566 | 1596 |
| 1567 | 1597 |
| 1568 Object* JSObject::SetProperty(String* name, | 1598 Object* JSObject::SetProperty(String* name, |
| 1569 Object* value, | 1599 Object* value, |
| 1570 PropertyAttributes attributes) { | 1600 PropertyAttributes attributes) { |
| 1571 LookupResult result; | 1601 LookupResult result; |
| 1572 LocalLookup(name, &result); | 1602 LocalLookup(name, &result); |
| 1573 return SetProperty(&result, name, value, attributes); | 1603 return SetProperty(&result, name, value, attributes); |
| 1574 } | 1604 } |
| 1575 | 1605 |
| 1576 | 1606 |
| 1577 Object* JSObject::SetPropertyWithCallback(Object* structure, | 1607 Object* JSObject::SetPropertyWithCallback(Object* structure, |
| 1578 String* name, | 1608 String* name, |
| 1579 Object* value, | 1609 Object* value, |
| 1580 JSObject* holder) { | 1610 JSObject* holder) { |
| 1611 Heap* heap = GetHeap(); |
| 1581 HandleScope scope; | 1612 HandleScope scope; |
| 1582 | 1613 |
| 1583 // We should never get here to initialize a const with the hole | 1614 // We should never get here to initialize a const with the hole |
| 1584 // value since a const declaration would conflict with the setter. | 1615 // value since a const declaration would conflict with the setter. |
| 1585 ASSERT(!value->IsTheHole()); | 1616 ASSERT(!value->IsTheHole()); |
| 1586 Handle<Object> value_handle(value); | 1617 Handle<Object> value_handle(value); |
| 1587 | 1618 |
| 1588 // To accommodate both the old and the new api we switch on the | 1619 // To accommodate both the old and the new api we switch on the |
| 1589 // data structure used to store the callbacks. Eventually proxy | 1620 // data structure used to store the callbacks. Eventually proxy |
| 1590 // callbacks should be phased out. | 1621 // callbacks should be phased out. |
| (...skipping 28 matching lines...) Expand all Loading... |
| 1619 } | 1650 } |
| 1620 | 1651 |
| 1621 if (structure->IsFixedArray()) { | 1652 if (structure->IsFixedArray()) { |
| 1622 Object* setter = FixedArray::cast(structure)->get(kSetterIndex); | 1653 Object* setter = FixedArray::cast(structure)->get(kSetterIndex); |
| 1623 if (setter->IsJSFunction()) { | 1654 if (setter->IsJSFunction()) { |
| 1624 return SetPropertyWithDefinedSetter(JSFunction::cast(setter), value); | 1655 return SetPropertyWithDefinedSetter(JSFunction::cast(setter), value); |
| 1625 } else { | 1656 } else { |
| 1626 Handle<String> key(name); | 1657 Handle<String> key(name); |
| 1627 Handle<Object> holder_handle(holder); | 1658 Handle<Object> holder_handle(holder); |
| 1628 Handle<Object> args[2] = { key, holder_handle }; | 1659 Handle<Object> args[2] = { key, holder_handle }; |
| 1629 return Isolate::Current()->Throw( | 1660 return heap->isolate()->Throw( |
| 1630 *Factory::NewTypeError("no_setter_in_callback", | 1661 *Factory::NewTypeError("no_setter_in_callback", |
| 1631 HandleVector(args, 2))); | 1662 HandleVector(args, 2))); |
| 1632 } | 1663 } |
| 1633 } | 1664 } |
| 1634 | 1665 |
| 1635 UNREACHABLE(); | 1666 UNREACHABLE(); |
| 1636 return NULL; | 1667 return NULL; |
| 1637 } | 1668 } |
| 1638 | 1669 |
| 1639 | 1670 |
| 1640 Object* JSObject::SetPropertyWithDefinedSetter(JSFunction* setter, | 1671 Object* JSObject::SetPropertyWithDefinedSetter(JSFunction* setter, |
| 1641 Object* value) { | 1672 Object* value) { |
| 1673 Heap* heap = GetHeap(); |
| 1642 Handle<Object> value_handle(value); | 1674 Handle<Object> value_handle(value); |
| 1643 Handle<JSFunction> fun(JSFunction::cast(setter)); | 1675 Handle<JSFunction> fun(JSFunction::cast(setter)); |
| 1644 Handle<JSObject> self(this); | 1676 Handle<JSObject> self(this); |
| 1645 #ifdef ENABLE_DEBUGGER_SUPPORT | 1677 #ifdef ENABLE_DEBUGGER_SUPPORT |
| 1646 Debug* debug = Isolate::Current()->debug(); | 1678 Debug* debug = heap->isolate()->debug(); |
| 1647 // Handle stepping into a setter if step into is active. | 1679 // Handle stepping into a setter if step into is active. |
| 1648 if (debug->StepInActive()) { | 1680 if (debug->StepInActive()) { |
| 1649 debug->HandleStepIn(fun, Handle<Object>::null(), 0, false); | 1681 debug->HandleStepIn(fun, Handle<Object>::null(), 0, false); |
| 1650 } | 1682 } |
| 1651 #endif | 1683 #endif |
| 1652 bool has_pending_exception; | 1684 bool has_pending_exception; |
| 1653 Object** argv[] = { value_handle.location() }; | 1685 Object** argv[] = { value_handle.location() }; |
| 1654 Execution::Call(fun, self, 1, argv, &has_pending_exception); | 1686 Execution::Call(fun, self, 1, argv, &has_pending_exception); |
| 1655 // Check for pending exception and return the result. | 1687 // Check for pending exception and return the result. |
| 1656 if (has_pending_exception) return Failure::Exception(); | 1688 if (has_pending_exception) return Failure::Exception(); |
| 1657 return *value_handle; | 1689 return *value_handle; |
| 1658 } | 1690 } |
| 1659 | 1691 |
| 1660 | 1692 |
| 1661 void JSObject::LookupCallbackSetterInPrototypes(String* name, | 1693 void JSObject::LookupCallbackSetterInPrototypes(String* name, |
| 1662 LookupResult* result) { | 1694 LookupResult* result) { |
| 1663 Heap* heap = HEAP; | 1695 Heap* heap = GetHeap(); |
| 1664 for (Object* pt = GetPrototype(); | 1696 for (Object* pt = GetPrototype(); |
| 1665 pt != heap->null_value(); | 1697 pt != heap->null_value(); |
| 1666 pt = pt->GetPrototype()) { | 1698 pt = pt->GetPrototype()) { |
| 1667 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); | 1699 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); |
| 1668 if (result->IsProperty()) { | 1700 if (result->IsProperty()) { |
| 1669 if (result->IsReadOnly()) { | 1701 if (result->IsReadOnly()) { |
| 1670 result->NotFound(); | 1702 result->NotFound(); |
| 1671 return; | 1703 return; |
| 1672 } | 1704 } |
| 1673 if (result->type() == CALLBACKS) { | 1705 if (result->type() == CALLBACKS) { |
| 1674 return; | 1706 return; |
| 1675 } | 1707 } |
| 1676 } | 1708 } |
| 1677 } | 1709 } |
| 1678 result->NotFound(); | 1710 result->NotFound(); |
| 1679 } | 1711 } |
| 1680 | 1712 |
| 1681 | 1713 |
| 1682 bool JSObject::SetElementWithCallbackSetterInPrototypes(uint32_t index, | 1714 bool JSObject::SetElementWithCallbackSetterInPrototypes(uint32_t index, |
| 1683 Object* value) { | 1715 Object* value) { |
| 1684 Heap* heap = HEAP; | 1716 Heap* heap = GetHeap(); |
| 1685 for (Object* pt = GetPrototype(); | 1717 for (Object* pt = GetPrototype(); |
| 1686 pt != heap->null_value(); | 1718 pt != heap->null_value(); |
| 1687 pt = pt->GetPrototype()) { | 1719 pt = pt->GetPrototype()) { |
| 1688 if (!JSObject::cast(pt)->HasDictionaryElements()) { | 1720 if (!JSObject::cast(pt)->HasDictionaryElements()) { |
| 1689 continue; | 1721 continue; |
| 1690 } | 1722 } |
| 1691 NumberDictionary* dictionary = JSObject::cast(pt)->element_dictionary(); | 1723 NumberDictionary* dictionary = JSObject::cast(pt)->element_dictionary(); |
| 1692 int entry = dictionary->FindEntry(index); | 1724 int entry = dictionary->FindEntry(index); |
| 1693 if (entry != NumberDictionary::kNotFound) { | 1725 if (entry != NumberDictionary::kNotFound) { |
| 1694 Object* element = dictionary->ValueAt(entry); | 1726 Object* element = dictionary->ValueAt(entry); |
| 1695 PropertyDetails details = dictionary->DetailsAt(entry); | 1727 PropertyDetails details = dictionary->DetailsAt(entry); |
| 1696 if (details.type() == CALLBACKS) { | 1728 if (details.type() == CALLBACKS) { |
| 1697 SetElementWithCallback(element, index, value, JSObject::cast(pt)); | 1729 SetElementWithCallback(element, index, value, JSObject::cast(pt)); |
| 1698 return true; | 1730 return true; |
| 1699 } | 1731 } |
| 1700 } | 1732 } |
| 1701 } | 1733 } |
| 1702 return false; | 1734 return false; |
| 1703 } | 1735 } |
| 1704 | 1736 |
| 1705 | 1737 |
| 1706 void JSObject::LookupInDescriptor(String* name, LookupResult* result) { | 1738 void JSObject::LookupInDescriptor(String* name, LookupResult* result) { |
| 1739 Heap* heap = GetHeap(); |
| 1707 DescriptorArray* descriptors = map()->instance_descriptors(); | 1740 DescriptorArray* descriptors = map()->instance_descriptors(); |
| 1708 DescriptorLookupCache* descriptor_lookup_cache = Isolate::Current()-> | 1741 DescriptorLookupCache* descriptor_lookup_cache = heap->isolate()-> |
| 1709 descriptor_lookup_cache(); | 1742 descriptor_lookup_cache(); |
| 1710 int number = descriptor_lookup_cache->Lookup(descriptors, name); | 1743 int number = descriptor_lookup_cache->Lookup(descriptors, name); |
| 1711 | 1744 |
| 1712 if (number == DescriptorLookupCache::kAbsent) { | 1745 if (number == DescriptorLookupCache::kAbsent) { |
| 1713 number = descriptors->Search(name); | 1746 number = descriptors->Search(name); |
| 1714 descriptor_lookup_cache->Update(descriptors, name, number); | 1747 descriptor_lookup_cache->Update(descriptors, name, number); |
| 1715 } | 1748 } |
| 1716 if (number != DescriptorArray::kNotFound) { | 1749 if (number != DescriptorArray::kNotFound) { |
| 1717 result->DescriptorResult(this, descriptors->GetDetails(number), number); | 1750 result->DescriptorResult(this, descriptors->GetDetails(number), number); |
| 1718 } else { | 1751 } else { |
| (...skipping 53 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1772 void JSObject::LookupRealNamedProperty(String* name, LookupResult* result) { | 1805 void JSObject::LookupRealNamedProperty(String* name, LookupResult* result) { |
| 1773 LocalLookupRealNamedProperty(name, result); | 1806 LocalLookupRealNamedProperty(name, result); |
| 1774 if (result->IsProperty()) return; | 1807 if (result->IsProperty()) return; |
| 1775 | 1808 |
| 1776 LookupRealNamedPropertyInPrototypes(name, result); | 1809 LookupRealNamedPropertyInPrototypes(name, result); |
| 1777 } | 1810 } |
| 1778 | 1811 |
| 1779 | 1812 |
| 1780 void JSObject::LookupRealNamedPropertyInPrototypes(String* name, | 1813 void JSObject::LookupRealNamedPropertyInPrototypes(String* name, |
| 1781 LookupResult* result) { | 1814 LookupResult* result) { |
| 1782 Heap* heap = HEAP; | 1815 Heap* heap = GetHeap(); |
| 1783 for (Object* pt = GetPrototype(); | 1816 for (Object* pt = GetPrototype(); |
| 1784 pt != heap->null_value(); | 1817 pt != heap->null_value(); |
| 1785 pt = JSObject::cast(pt)->GetPrototype()) { | 1818 pt = JSObject::cast(pt)->GetPrototype()) { |
| 1786 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); | 1819 JSObject::cast(pt)->LocalLookupRealNamedProperty(name, result); |
| 1787 if (result->IsProperty() && (result->type() != INTERCEPTOR)) return; | 1820 if (result->IsProperty() && (result->type() != INTERCEPTOR)) return; |
| 1788 } | 1821 } |
| 1789 result->NotFound(); | 1822 result->NotFound(); |
| 1790 } | 1823 } |
| 1791 | 1824 |
| 1792 | 1825 |
| 1793 // We only need to deal with CALLBACKS and INTERCEPTORS | 1826 // We only need to deal with CALLBACKS and INTERCEPTORS |
| 1794 Object* JSObject::SetPropertyWithFailedAccessCheck(LookupResult* result, | 1827 Object* JSObject::SetPropertyWithFailedAccessCheck(LookupResult* result, |
| 1795 String* name, | 1828 String* name, |
| 1796 Object* value) { | 1829 Object* value) { |
| 1830 Heap* heap = GetHeap(); |
| 1831 |
| 1797 if (!result->IsProperty()) { | 1832 if (!result->IsProperty()) { |
| 1798 LookupCallbackSetterInPrototypes(name, result); | 1833 LookupCallbackSetterInPrototypes(name, result); |
| 1799 } | 1834 } |
| 1800 | 1835 |
| 1801 if (result->IsProperty()) { | 1836 if (result->IsProperty()) { |
| 1802 if (!result->IsReadOnly()) { | 1837 if (!result->IsReadOnly()) { |
| 1803 switch (result->type()) { | 1838 switch (result->type()) { |
| 1804 case CALLBACKS: { | 1839 case CALLBACKS: { |
| 1805 Object* obj = result->GetCallbackObject(); | 1840 Object* obj = result->GetCallbackObject(); |
| 1806 if (obj->IsAccessorInfo()) { | 1841 if (obj->IsAccessorInfo()) { |
| (...skipping 17 matching lines...) Expand all Loading... |
| 1824 } | 1859 } |
| 1825 break; | 1860 break; |
| 1826 } | 1861 } |
| 1827 default: { | 1862 default: { |
| 1828 break; | 1863 break; |
| 1829 } | 1864 } |
| 1830 } | 1865 } |
| 1831 } | 1866 } |
| 1832 } | 1867 } |
| 1833 | 1868 |
| 1834 Isolate::Current()->ReportFailedAccessCheck(this, v8::ACCESS_SET); | 1869 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET); |
| 1835 return value; | 1870 return value; |
| 1836 } | 1871 } |
| 1837 | 1872 |
| 1838 | 1873 |
| 1839 Object* JSObject::SetProperty(LookupResult* result, | 1874 Object* JSObject::SetProperty(LookupResult* result, |
| 1840 String* name, | 1875 String* name, |
| 1841 Object* value, | 1876 Object* value, |
| 1842 PropertyAttributes attributes) { | 1877 PropertyAttributes attributes) { |
| 1878 Heap* heap = GetHeap(); |
| 1879 |
| 1843 // Make sure that the top context does not change when doing callbacks or | 1880 // Make sure that the top context does not change when doing callbacks or |
| 1844 // interceptor calls. | 1881 // interceptor calls. |
| 1845 AssertNoContextChange ncc; | 1882 AssertNoContextChange ncc; |
| 1846 | 1883 |
| 1847 // Optimization for 2-byte strings often used as keys in a decompression | 1884 // Optimization for 2-byte strings often used as keys in a decompression |
| 1848 // dictionary. We make these short keys into symbols to avoid constantly | 1885 // dictionary. We make these short keys into symbols to avoid constantly |
| 1849 // reallocating them. | 1886 // reallocating them. |
| 1850 if (!name->IsSymbol() && name->length() <= 2) { | 1887 if (!name->IsSymbol() && name->length() <= 2) { |
| 1851 Object* symbol_version = HEAP->LookupSymbol(name); | 1888 Object* symbol_version = heap->LookupSymbol(name); |
| 1852 if (!symbol_version->IsFailure()) name = String::cast(symbol_version); | 1889 if (!symbol_version->IsFailure()) name = String::cast(symbol_version); |
| 1853 } | 1890 } |
| 1854 | 1891 |
| 1855 // Check access rights if needed. | 1892 // Check access rights if needed. |
| 1856 if (IsAccessCheckNeeded() | 1893 if (IsAccessCheckNeeded() |
| 1857 && !Isolate::Current()->MayNamedAccess(this, name, v8::ACCESS_SET)) { | 1894 && !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_SET)) { |
| 1858 return SetPropertyWithFailedAccessCheck(result, name, value); | 1895 return SetPropertyWithFailedAccessCheck(result, name, value); |
| 1859 } | 1896 } |
| 1860 | 1897 |
| 1861 if (IsJSGlobalProxy()) { | 1898 if (IsJSGlobalProxy()) { |
| 1862 Object* proto = GetPrototype(); | 1899 Object* proto = GetPrototype(); |
| 1863 if (proto->IsNull()) return value; | 1900 if (proto->IsNull()) return value; |
| 1864 ASSERT(proto->IsJSGlobalObject()); | 1901 ASSERT(proto->IsJSGlobalObject()); |
| 1865 return JSObject::cast(proto)->SetProperty(result, name, value, attributes); | 1902 return JSObject::cast(proto)->SetProperty(result, name, value, attributes); |
| 1866 } | 1903 } |
| 1867 | 1904 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1927 // Set a real local property, even if it is READ_ONLY. If the property is not | 1964 // Set a real local property, even if it is READ_ONLY. If the property is not |
| 1928 // present, add it with attributes NONE. This code is an exact clone of | 1965 // present, add it with attributes NONE. This code is an exact clone of |
| 1929 // SetProperty, with the check for IsReadOnly and the check for a | 1966 // SetProperty, with the check for IsReadOnly and the check for a |
| 1930 // callback setter removed. The two lines looking up the LookupResult | 1967 // callback setter removed. The two lines looking up the LookupResult |
| 1931 // result are also added. If one of the functions is changed, the other | 1968 // result are also added. If one of the functions is changed, the other |
| 1932 // should be. | 1969 // should be. |
| 1933 Object* JSObject::IgnoreAttributesAndSetLocalProperty( | 1970 Object* JSObject::IgnoreAttributesAndSetLocalProperty( |
| 1934 String* name, | 1971 String* name, |
| 1935 Object* value, | 1972 Object* value, |
| 1936 PropertyAttributes attributes) { | 1973 PropertyAttributes attributes) { |
| 1974 Heap* heap = GetHeap(); |
| 1975 |
| 1937 // Make sure that the top context does not change when doing callbacks or | 1976 // Make sure that the top context does not change when doing callbacks or |
| 1938 // interceptor calls. | 1977 // interceptor calls. |
| 1939 AssertNoContextChange ncc; | 1978 AssertNoContextChange ncc; |
| 1940 LookupResult result; | 1979 LookupResult result; |
| 1941 LocalLookup(name, &result); | 1980 LocalLookup(name, &result); |
| 1942 // Check access rights if needed. | 1981 // Check access rights if needed. |
| 1943 if (IsAccessCheckNeeded() | 1982 if (IsAccessCheckNeeded() |
| 1944 && !Isolate::Current()->MayNamedAccess(this, name, v8::ACCESS_SET)) { | 1983 && !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_SET)) { |
| 1945 return SetPropertyWithFailedAccessCheck(&result, name, value); | 1984 return SetPropertyWithFailedAccessCheck(&result, name, value); |
| 1946 } | 1985 } |
| 1947 | 1986 |
| 1948 if (IsJSGlobalProxy()) { | 1987 if (IsJSGlobalProxy()) { |
| 1949 Object* proto = GetPrototype(); | 1988 Object* proto = GetPrototype(); |
| 1950 if (proto->IsNull()) return value; | 1989 if (proto->IsNull()) return value; |
| 1951 ASSERT(proto->IsJSGlobalObject()); | 1990 ASSERT(proto->IsJSGlobalObject()); |
| 1952 return JSObject::cast(proto)->IgnoreAttributesAndSetLocalProperty( | 1991 return JSObject::cast(proto)->IgnoreAttributesAndSetLocalProperty( |
| 1953 name, | 1992 name, |
| 1954 value, | 1993 value, |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2081 LookupResult result; | 2120 LookupResult result; |
| 2082 Lookup(key, &result); | 2121 Lookup(key, &result); |
| 2083 return GetPropertyAttribute(receiver, &result, key, true); | 2122 return GetPropertyAttribute(receiver, &result, key, true); |
| 2084 } | 2123 } |
| 2085 | 2124 |
| 2086 | 2125 |
| 2087 PropertyAttributes JSObject::GetPropertyAttribute(JSObject* receiver, | 2126 PropertyAttributes JSObject::GetPropertyAttribute(JSObject* receiver, |
| 2088 LookupResult* result, | 2127 LookupResult* result, |
| 2089 String* name, | 2128 String* name, |
| 2090 bool continue_search) { | 2129 bool continue_search) { |
| 2130 Heap* heap = GetHeap(); |
| 2091 // Check access rights if needed. | 2131 // Check access rights if needed. |
| 2092 if (IsAccessCheckNeeded() && | 2132 if (IsAccessCheckNeeded() && |
| 2093 !Isolate::Current()->MayNamedAccess(this, name, v8::ACCESS_HAS)) { | 2133 !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_HAS)) { |
| 2094 return GetPropertyAttributeWithFailedAccessCheck(receiver, | 2134 return GetPropertyAttributeWithFailedAccessCheck(receiver, |
| 2095 result, | 2135 result, |
| 2096 name, | 2136 name, |
| 2097 continue_search); | 2137 continue_search); |
| 2098 } | 2138 } |
| 2099 if (result->IsProperty()) { | 2139 if (result->IsProperty()) { |
| 2100 switch (result->type()) { | 2140 switch (result->type()) { |
| 2101 case NORMAL: // fall through | 2141 case NORMAL: // fall through |
| 2102 case FIELD: | 2142 case FIELD: |
| 2103 case CONSTANT_FUNCTION: | 2143 case CONSTANT_FUNCTION: |
| (...skipping 24 matching lines...) Expand all Loading... |
| 2128 } | 2168 } |
| 2129 | 2169 |
| 2130 | 2170 |
| 2131 Object* JSObject::NormalizeProperties(PropertyNormalizationMode mode, | 2171 Object* JSObject::NormalizeProperties(PropertyNormalizationMode mode, |
| 2132 int expected_additional_properties) { | 2172 int expected_additional_properties) { |
| 2133 if (!HasFastProperties()) return this; | 2173 if (!HasFastProperties()) return this; |
| 2134 | 2174 |
| 2135 // The global object is always normalized. | 2175 // The global object is always normalized. |
| 2136 ASSERT(!IsGlobalObject()); | 2176 ASSERT(!IsGlobalObject()); |
| 2137 | 2177 |
| 2178 Heap* heap = GetHeap(); |
| 2179 |
| 2138 // Allocate new content. | 2180 // Allocate new content. |
| 2139 int property_count = map()->NumberOfDescribedProperties(); | 2181 int property_count = map()->NumberOfDescribedProperties(); |
| 2140 if (expected_additional_properties > 0) { | 2182 if (expected_additional_properties > 0) { |
| 2141 property_count += expected_additional_properties; | 2183 property_count += expected_additional_properties; |
| 2142 } else { | 2184 } else { |
| 2143 property_count += 2; // Make space for two more properties. | 2185 property_count += 2; // Make space for two more properties. |
| 2144 } | 2186 } |
| 2145 Object* obj = | 2187 Object* obj = |
| 2146 StringDictionary::Allocate(property_count); | 2188 StringDictionary::Allocate(property_count); |
| 2147 if (obj->IsFailure()) return obj; | 2189 if (obj->IsFailure()) return obj; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2197 if (obj->IsFailure()) return obj; | 2239 if (obj->IsFailure()) return obj; |
| 2198 Map* new_map = Map::cast(obj); | 2240 Map* new_map = Map::cast(obj); |
| 2199 | 2241 |
| 2200 // Clear inobject properties if needed by adjusting the instance size and | 2242 // Clear inobject properties if needed by adjusting the instance size and |
| 2201 // putting in a filler object instead of the inobject properties. | 2243 // putting in a filler object instead of the inobject properties. |
| 2202 if (mode == CLEAR_INOBJECT_PROPERTIES && map()->inobject_properties() > 0) { | 2244 if (mode == CLEAR_INOBJECT_PROPERTIES && map()->inobject_properties() > 0) { |
| 2203 int instance_size_delta = map()->inobject_properties() * kPointerSize; | 2245 int instance_size_delta = map()->inobject_properties() * kPointerSize; |
| 2204 int new_instance_size = map()->instance_size() - instance_size_delta; | 2246 int new_instance_size = map()->instance_size() - instance_size_delta; |
| 2205 new_map->set_inobject_properties(0); | 2247 new_map->set_inobject_properties(0); |
| 2206 new_map->set_instance_size(new_instance_size); | 2248 new_map->set_instance_size(new_instance_size); |
| 2207 new_map->set_scavenger(HEAP->GetScavenger(new_map->instance_type(), | 2249 new_map->set_scavenger(heap->GetScavenger(new_map->instance_type(), |
| 2208 new_map->instance_size())); | 2250 new_map->instance_size())); |
| 2209 HEAP->CreateFillerObjectAt(this->address() + new_instance_size, | 2251 heap->CreateFillerObjectAt(this->address() + new_instance_size, |
| 2210 instance_size_delta); | 2252 instance_size_delta); |
| 2211 } | 2253 } |
| 2212 new_map->set_unused_property_fields(0); | 2254 new_map->set_unused_property_fields(0); |
| 2213 | 2255 |
| 2214 // We have now successfully allocated all the necessary objects. | 2256 // We have now successfully allocated all the necessary objects. |
| 2215 // Changes can now be made with the guarantee that all of them take effect. | 2257 // Changes can now be made with the guarantee that all of them take effect. |
| 2216 set_map(new_map); | 2258 set_map(new_map); |
| 2217 map()->set_instance_descriptors(HEAP->empty_descriptor_array()); | 2259 map()->set_instance_descriptors(heap->empty_descriptor_array()); |
| 2218 | 2260 |
| 2219 set_properties(dictionary); | 2261 set_properties(dictionary); |
| 2220 | 2262 |
| 2221 COUNTERS->props_to_dictionary()->Increment(); | 2263 heap->isolate()->counters()->props_to_dictionary()->Increment(); |
| 2222 | 2264 |
| 2223 #ifdef DEBUG | 2265 #ifdef DEBUG |
| 2224 if (FLAG_trace_normalization) { | 2266 if (FLAG_trace_normalization) { |
| 2225 PrintF("Object properties have been normalized:\n"); | 2267 PrintF("Object properties have been normalized:\n"); |
| 2226 Print(); | 2268 Print(); |
| 2227 } | 2269 } |
| 2228 #endif | 2270 #endif |
| 2229 return this; | 2271 return this; |
| 2230 } | 2272 } |
| 2231 | 2273 |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2266 if (result->IsFailure()) return result; | 2308 if (result->IsFailure()) return result; |
| 2267 dictionary = NumberDictionary::cast(result); | 2309 dictionary = NumberDictionary::cast(result); |
| 2268 } | 2310 } |
| 2269 } | 2311 } |
| 2270 // Switch to using the dictionary as the backing storage for | 2312 // Switch to using the dictionary as the backing storage for |
| 2271 // elements. Set the new map first to satify the elements type | 2313 // elements. Set the new map first to satify the elements type |
| 2272 // assert in set_elements(). | 2314 // assert in set_elements(). |
| 2273 set_map(new_map); | 2315 set_map(new_map); |
| 2274 set_elements(dictionary); | 2316 set_elements(dictionary); |
| 2275 | 2317 |
| 2276 COUNTERS->elements_to_dictionary()->Increment(); | 2318 new_map->GetHeap()->isolate()->counters()->elements_to_dictionary()-> |
| 2319 Increment(); |
| 2277 | 2320 |
| 2278 #ifdef DEBUG | 2321 #ifdef DEBUG |
| 2279 if (FLAG_trace_normalization) { | 2322 if (FLAG_trace_normalization) { |
| 2280 PrintF("Object elements have been normalized:\n"); | 2323 PrintF("Object elements have been normalized:\n"); |
| 2281 Print(); | 2324 Print(); |
| 2282 } | 2325 } |
| 2283 #endif | 2326 #endif |
| 2284 | 2327 |
| 2285 return this; | 2328 return this; |
| 2286 } | 2329 } |
| 2287 | 2330 |
| 2288 | 2331 |
| 2289 Object* JSObject::DeletePropertyPostInterceptor(String* name, DeleteMode mode) { | 2332 Object* JSObject::DeletePropertyPostInterceptor(String* name, DeleteMode mode) { |
| 2290 // Check local property, ignore interceptor. | 2333 // Check local property, ignore interceptor. |
| 2334 Heap* heap = GetHeap(); |
| 2291 LookupResult result; | 2335 LookupResult result; |
| 2292 LocalLookupRealNamedProperty(name, &result); | 2336 LocalLookupRealNamedProperty(name, &result); |
| 2293 if (!result.IsProperty()) return HEAP->true_value(); | 2337 if (!result.IsProperty()) return heap->true_value(); |
| 2294 | 2338 |
| 2295 // Normalize object if needed. | 2339 // Normalize object if needed. |
| 2296 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 2340 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
| 2297 if (obj->IsFailure()) return obj; | 2341 if (obj->IsFailure()) return obj; |
| 2298 | 2342 |
| 2299 return DeleteNormalizedProperty(name, mode); | 2343 return DeleteNormalizedProperty(name, mode); |
| 2300 } | 2344 } |
| 2301 | 2345 |
| 2302 | 2346 |
| 2303 Object* JSObject::DeletePropertyWithInterceptor(String* name) { | 2347 Object* JSObject::DeletePropertyWithInterceptor(String* name) { |
| (...skipping 22 matching lines...) Expand all Loading... |
| 2326 Object* raw_result = | 2370 Object* raw_result = |
| 2327 this_handle->DeletePropertyPostInterceptor(*name_handle, NORMAL_DELETION); | 2371 this_handle->DeletePropertyPostInterceptor(*name_handle, NORMAL_DELETION); |
| 2328 RETURN_IF_SCHEDULED_EXCEPTION(); | 2372 RETURN_IF_SCHEDULED_EXCEPTION(); |
| 2329 return raw_result; | 2373 return raw_result; |
| 2330 } | 2374 } |
| 2331 | 2375 |
| 2332 | 2376 |
| 2333 Object* JSObject::DeleteElementPostInterceptor(uint32_t index, | 2377 Object* JSObject::DeleteElementPostInterceptor(uint32_t index, |
| 2334 DeleteMode mode) { | 2378 DeleteMode mode) { |
| 2335 ASSERT(!HasPixelElements() && !HasExternalArrayElements()); | 2379 ASSERT(!HasPixelElements() && !HasExternalArrayElements()); |
| 2380 Heap* heap = GetHeap(); |
| 2336 switch (GetElementsKind()) { | 2381 switch (GetElementsKind()) { |
| 2337 case FAST_ELEMENTS: { | 2382 case FAST_ELEMENTS: { |
| 2338 uint32_t length = IsJSArray() ? | 2383 uint32_t length = IsJSArray() ? |
| 2339 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : | 2384 static_cast<uint32_t>(Smi::cast(JSArray::cast(this)->length())->value()) : |
| 2340 static_cast<uint32_t>(FixedArray::cast(elements())->length()); | 2385 static_cast<uint32_t>(FixedArray::cast(elements())->length()); |
| 2341 if (index < length) { | 2386 if (index < length) { |
| 2342 FixedArray::cast(elements())->set_the_hole(index); | 2387 FixedArray::cast(elements())->set_the_hole(index); |
| 2343 } | 2388 } |
| 2344 break; | 2389 break; |
| 2345 } | 2390 } |
| 2346 case DICTIONARY_ELEMENTS: { | 2391 case DICTIONARY_ELEMENTS: { |
| 2347 NumberDictionary* dictionary = element_dictionary(); | 2392 NumberDictionary* dictionary = element_dictionary(); |
| 2348 int entry = dictionary->FindEntry(index); | 2393 int entry = dictionary->FindEntry(index); |
| 2349 if (entry != NumberDictionary::kNotFound) { | 2394 if (entry != NumberDictionary::kNotFound) { |
| 2350 return dictionary->DeleteProperty(entry, mode); | 2395 return dictionary->DeleteProperty(entry, mode); |
| 2351 } | 2396 } |
| 2352 break; | 2397 break; |
| 2353 } | 2398 } |
| 2354 default: | 2399 default: |
| 2355 UNREACHABLE(); | 2400 UNREACHABLE(); |
| 2356 break; | 2401 break; |
| 2357 } | 2402 } |
| 2358 return HEAP->true_value(); | 2403 return heap->true_value(); |
| 2359 } | 2404 } |
| 2360 | 2405 |
| 2361 | 2406 |
| 2362 Object* JSObject::DeleteElementWithInterceptor(uint32_t index) { | 2407 Object* JSObject::DeleteElementWithInterceptor(uint32_t index) { |
| 2408 Heap* heap = GetHeap(); |
| 2363 // Make sure that the top context does not change when doing | 2409 // Make sure that the top context does not change when doing |
| 2364 // callbacks or interceptor calls. | 2410 // callbacks or interceptor calls. |
| 2365 AssertNoContextChange ncc; | 2411 AssertNoContextChange ncc; |
| 2366 HandleScope scope; | 2412 HandleScope scope; |
| 2367 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); | 2413 Handle<InterceptorInfo> interceptor(GetIndexedInterceptor()); |
| 2368 if (interceptor->deleter()->IsUndefined()) return HEAP->false_value(); | 2414 if (interceptor->deleter()->IsUndefined()) return heap->false_value(); |
| 2369 v8::IndexedPropertyDeleter deleter = | 2415 v8::IndexedPropertyDeleter deleter = |
| 2370 v8::ToCData<v8::IndexedPropertyDeleter>(interceptor->deleter()); | 2416 v8::ToCData<v8::IndexedPropertyDeleter>(interceptor->deleter()); |
| 2371 Handle<JSObject> this_handle(this); | 2417 Handle<JSObject> this_handle(this); |
| 2372 LOG(ApiIndexedPropertyAccess("interceptor-indexed-delete", this, index)); | 2418 LOG(ApiIndexedPropertyAccess("interceptor-indexed-delete", this, index)); |
| 2373 CustomArguments args(interceptor->data(), this, this); | 2419 CustomArguments args(interceptor->data(), this, this); |
| 2374 v8::AccessorInfo info(args.end()); | 2420 v8::AccessorInfo info(args.end()); |
| 2375 v8::Handle<v8::Boolean> result; | 2421 v8::Handle<v8::Boolean> result; |
| 2376 { | 2422 { |
| 2377 // Leaving JavaScript. | 2423 // Leaving JavaScript. |
| 2378 VMState state(EXTERNAL); | 2424 VMState state(EXTERNAL); |
| 2379 result = deleter(index, info); | 2425 result = deleter(index, info); |
| 2380 } | 2426 } |
| 2381 RETURN_IF_SCHEDULED_EXCEPTION(); | 2427 RETURN_IF_SCHEDULED_EXCEPTION(); |
| 2382 if (!result.IsEmpty()) { | 2428 if (!result.IsEmpty()) { |
| 2383 ASSERT(result->IsBoolean()); | 2429 ASSERT(result->IsBoolean()); |
| 2384 return *v8::Utils::OpenHandle(*result); | 2430 return *v8::Utils::OpenHandle(*result); |
| 2385 } | 2431 } |
| 2386 Object* raw_result = | 2432 Object* raw_result = |
| 2387 this_handle->DeleteElementPostInterceptor(index, NORMAL_DELETION); | 2433 this_handle->DeleteElementPostInterceptor(index, NORMAL_DELETION); |
| 2388 RETURN_IF_SCHEDULED_EXCEPTION(); | 2434 RETURN_IF_SCHEDULED_EXCEPTION(); |
| 2389 return raw_result; | 2435 return raw_result; |
| 2390 } | 2436 } |
| 2391 | 2437 |
| 2392 | 2438 |
| 2393 Object* JSObject::DeleteElement(uint32_t index, DeleteMode mode) { | 2439 Object* JSObject::DeleteElement(uint32_t index, DeleteMode mode) { |
| 2440 Heap* heap = GetHeap(); |
| 2394 // Check access rights if needed. | 2441 // Check access rights if needed. |
| 2395 if (IsAccessCheckNeeded() && | 2442 if (IsAccessCheckNeeded() && |
| 2396 !Isolate::Current()->MayIndexedAccess(this, index, v8::ACCESS_DELETE)) { | 2443 !heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_DELETE)) { |
| 2397 Isolate::Current()->ReportFailedAccessCheck(this, v8::ACCESS_DELETE); | 2444 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_DELETE); |
| 2398 return HEAP->false_value(); | 2445 return heap->false_value(); |
| 2399 } | 2446 } |
| 2400 | 2447 |
| 2401 if (IsJSGlobalProxy()) { | 2448 if (IsJSGlobalProxy()) { |
| 2402 Object* proto = GetPrototype(); | 2449 Object* proto = GetPrototype(); |
| 2403 if (proto->IsNull()) return HEAP->false_value(); | 2450 if (proto->IsNull()) return heap->false_value(); |
| 2404 ASSERT(proto->IsJSGlobalObject()); | 2451 ASSERT(proto->IsJSGlobalObject()); |
| 2405 return JSGlobalObject::cast(proto)->DeleteElement(index, mode); | 2452 return JSGlobalObject::cast(proto)->DeleteElement(index, mode); |
| 2406 } | 2453 } |
| 2407 | 2454 |
| 2408 if (HasIndexedInterceptor()) { | 2455 if (HasIndexedInterceptor()) { |
| 2409 // Skip interceptor if forcing deletion. | 2456 // Skip interceptor if forcing deletion. |
| 2410 if (mode == FORCE_DELETION) { | 2457 if (mode == FORCE_DELETION) { |
| 2411 return DeleteElementPostInterceptor(index, mode); | 2458 return DeleteElementPostInterceptor(index, mode); |
| 2412 } | 2459 } |
| 2413 return DeleteElementWithInterceptor(index); | 2460 return DeleteElementWithInterceptor(index); |
| (...skipping 25 matching lines...) Expand all Loading... |
| 2439 int entry = dictionary->FindEntry(index); | 2486 int entry = dictionary->FindEntry(index); |
| 2440 if (entry != NumberDictionary::kNotFound) { | 2487 if (entry != NumberDictionary::kNotFound) { |
| 2441 return dictionary->DeleteProperty(entry, mode); | 2488 return dictionary->DeleteProperty(entry, mode); |
| 2442 } | 2489 } |
| 2443 break; | 2490 break; |
| 2444 } | 2491 } |
| 2445 default: | 2492 default: |
| 2446 UNREACHABLE(); | 2493 UNREACHABLE(); |
| 2447 break; | 2494 break; |
| 2448 } | 2495 } |
| 2449 return HEAP->true_value(); | 2496 return heap->true_value(); |
| 2450 } | 2497 } |
| 2451 | 2498 |
| 2452 | 2499 |
| 2453 Object* JSObject::DeleteProperty(String* name, DeleteMode mode) { | 2500 Object* JSObject::DeleteProperty(String* name, DeleteMode mode) { |
| 2501 Heap* heap = GetHeap(); |
| 2454 // ECMA-262, 3rd, 8.6.2.5 | 2502 // ECMA-262, 3rd, 8.6.2.5 |
| 2455 ASSERT(name->IsString()); | 2503 ASSERT(name->IsString()); |
| 2456 | 2504 |
| 2457 // Check access rights if needed. | 2505 // Check access rights if needed. |
| 2458 if (IsAccessCheckNeeded() && | 2506 if (IsAccessCheckNeeded() && |
| 2459 !Isolate::Current()->MayNamedAccess(this, name, v8::ACCESS_DELETE)) { | 2507 !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_DELETE)) { |
| 2460 Isolate::Current()->ReportFailedAccessCheck(this, v8::ACCESS_DELETE); | 2508 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_DELETE); |
| 2461 return HEAP->false_value(); | 2509 return heap->false_value(); |
| 2462 } | 2510 } |
| 2463 | 2511 |
| 2464 if (IsJSGlobalProxy()) { | 2512 if (IsJSGlobalProxy()) { |
| 2465 Object* proto = GetPrototype(); | 2513 Object* proto = GetPrototype(); |
| 2466 if (proto->IsNull()) return HEAP->false_value(); | 2514 if (proto->IsNull()) return heap->false_value(); |
| 2467 ASSERT(proto->IsJSGlobalObject()); | 2515 ASSERT(proto->IsJSGlobalObject()); |
| 2468 return JSGlobalObject::cast(proto)->DeleteProperty(name, mode); | 2516 return JSGlobalObject::cast(proto)->DeleteProperty(name, mode); |
| 2469 } | 2517 } |
| 2470 | 2518 |
| 2471 uint32_t index = 0; | 2519 uint32_t index = 0; |
| 2472 if (name->AsArrayIndex(&index)) { | 2520 if (name->AsArrayIndex(&index)) { |
| 2473 return DeleteElement(index, mode); | 2521 return DeleteElement(index, mode); |
| 2474 } else { | 2522 } else { |
| 2475 LookupResult result; | 2523 LookupResult result; |
| 2476 LocalLookup(name, &result); | 2524 LocalLookup(name, &result); |
| 2477 if (!result.IsProperty()) return HEAP->true_value(); | 2525 if (!result.IsProperty()) return heap->true_value(); |
| 2478 // Ignore attributes if forcing a deletion. | 2526 // Ignore attributes if forcing a deletion. |
| 2479 if (result.IsDontDelete() && mode != FORCE_DELETION) { | 2527 if (result.IsDontDelete() && mode != FORCE_DELETION) { |
| 2480 return HEAP->false_value(); | 2528 return heap->false_value(); |
| 2481 } | 2529 } |
| 2482 // Check for interceptor. | 2530 // Check for interceptor. |
| 2483 if (result.type() == INTERCEPTOR) { | 2531 if (result.type() == INTERCEPTOR) { |
| 2484 // Skip interceptor if forcing a deletion. | 2532 // Skip interceptor if forcing a deletion. |
| 2485 if (mode == FORCE_DELETION) { | 2533 if (mode == FORCE_DELETION) { |
| 2486 return DeletePropertyPostInterceptor(name, mode); | 2534 return DeletePropertyPostInterceptor(name, mode); |
| 2487 } | 2535 } |
| 2488 return DeletePropertyWithInterceptor(name); | 2536 return DeletePropertyWithInterceptor(name); |
| 2489 } | 2537 } |
| 2490 // Normalize object if needed. | 2538 // Normalize object if needed. |
| 2491 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); | 2539 Object* obj = NormalizeProperties(CLEAR_INOBJECT_PROPERTIES, 0); |
| 2492 if (obj->IsFailure()) return obj; | 2540 if (obj->IsFailure()) return obj; |
| 2493 // Make sure the properties are normalized before removing the entry. | 2541 // Make sure the properties are normalized before removing the entry. |
| 2494 return DeleteNormalizedProperty(name, mode); | 2542 return DeleteNormalizedProperty(name, mode); |
| 2495 } | 2543 } |
| 2496 } | 2544 } |
| 2497 | 2545 |
| 2498 | 2546 |
| 2499 // Check whether this object references another object. | 2547 // Check whether this object references another object. |
| 2500 bool JSObject::ReferencesObject(Object* obj) { | 2548 bool JSObject::ReferencesObject(Object* obj) { |
| 2549 Heap* heap = GetHeap(); |
| 2501 AssertNoAllocation no_alloc; | 2550 AssertNoAllocation no_alloc; |
| 2502 | 2551 |
| 2503 // Is the object the constructor for this object? | 2552 // Is the object the constructor for this object? |
| 2504 if (map()->constructor() == obj) { | 2553 if (map()->constructor() == obj) { |
| 2505 return true; | 2554 return true; |
| 2506 } | 2555 } |
| 2507 | 2556 |
| 2508 // Is the object the prototype for this object? | 2557 // Is the object the prototype for this object? |
| 2509 if (map()->prototype() == obj) { | 2558 if (map()->prototype() == obj) { |
| 2510 return true; | 2559 return true; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2550 } | 2599 } |
| 2551 default: | 2600 default: |
| 2552 UNREACHABLE(); | 2601 UNREACHABLE(); |
| 2553 break; | 2602 break; |
| 2554 } | 2603 } |
| 2555 | 2604 |
| 2556 // For functions check the context. | 2605 // For functions check the context. |
| 2557 if (IsJSFunction()) { | 2606 if (IsJSFunction()) { |
| 2558 // Get the constructor function for arguments array. | 2607 // Get the constructor function for arguments array. |
| 2559 JSObject* arguments_boilerplate = | 2608 JSObject* arguments_boilerplate = |
| 2560 Isolate::Current()->context()->global_context()-> | 2609 heap->isolate()->context()->global_context()-> |
| 2561 arguments_boilerplate(); | 2610 arguments_boilerplate(); |
| 2562 JSFunction* arguments_function = | 2611 JSFunction* arguments_function = |
| 2563 JSFunction::cast(arguments_boilerplate->map()->constructor()); | 2612 JSFunction::cast(arguments_boilerplate->map()->constructor()); |
| 2564 | 2613 |
| 2565 // Get the context and don't check if it is the global context. | 2614 // Get the context and don't check if it is the global context. |
| 2566 JSFunction* f = JSFunction::cast(this); | 2615 JSFunction* f = JSFunction::cast(this); |
| 2567 Context* context = f->context(); | 2616 Context* context = f->context(); |
| 2568 if (context->IsGlobalContext()) { | 2617 if (context->IsGlobalContext()) { |
| 2569 return false; | 2618 return false; |
| 2570 } | 2619 } |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2614 return new_map; | 2663 return new_map; |
| 2615 } | 2664 } |
| 2616 | 2665 |
| 2617 | 2666 |
| 2618 // Tests for the fast common case for property enumeration: | 2667 // Tests for the fast common case for property enumeration: |
| 2619 // - This object and all prototypes has an enum cache (which means that it has | 2668 // - This object and all prototypes has an enum cache (which means that it has |
| 2620 // no interceptors and needs no access checks). | 2669 // no interceptors and needs no access checks). |
| 2621 // - This object has no elements. | 2670 // - This object has no elements. |
| 2622 // - No prototype has enumerable properties/elements. | 2671 // - No prototype has enumerable properties/elements. |
| 2623 bool JSObject::IsSimpleEnum() { | 2672 bool JSObject::IsSimpleEnum() { |
| 2624 Heap* heap = HEAP; | 2673 Heap* heap = GetHeap(); |
| 2625 for (Object* o = this; | 2674 for (Object* o = this; |
| 2626 o != heap->null_value(); | 2675 o != heap->null_value(); |
| 2627 o = JSObject::cast(o)->GetPrototype()) { | 2676 o = JSObject::cast(o)->GetPrototype()) { |
| 2628 JSObject* curr = JSObject::cast(o); | 2677 JSObject* curr = JSObject::cast(o); |
| 2629 if (!curr->map()->instance_descriptors()->HasEnumCache()) return false; | 2678 if (!curr->map()->instance_descriptors()->HasEnumCache()) return false; |
| 2630 ASSERT(!curr->HasNamedInterceptor()); | 2679 ASSERT(!curr->HasNamedInterceptor()); |
| 2631 ASSERT(!curr->HasIndexedInterceptor()); | 2680 ASSERT(!curr->HasIndexedInterceptor()); |
| 2632 ASSERT(!curr->IsAccessCheckNeeded()); | 2681 ASSERT(!curr->IsAccessCheckNeeded()); |
| 2633 if (curr->NumberOfEnumElements() > 0) return false; | 2682 if (curr->NumberOfEnumElements() > 0) return false; |
| 2634 if (curr != this) { | 2683 if (curr != this) { |
| (...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2682 return descs->GetCallbacks(i); | 2731 return descs->GetCallbacks(i); |
| 2683 } | 2732 } |
| 2684 } | 2733 } |
| 2685 return NULL; | 2734 return NULL; |
| 2686 } | 2735 } |
| 2687 | 2736 |
| 2688 | 2737 |
| 2689 void JSObject::LocalLookup(String* name, LookupResult* result) { | 2738 void JSObject::LocalLookup(String* name, LookupResult* result) { |
| 2690 ASSERT(name->IsString()); | 2739 ASSERT(name->IsString()); |
| 2691 | 2740 |
| 2741 Heap* heap = GetHeap(); |
| 2742 |
| 2692 if (IsJSGlobalProxy()) { | 2743 if (IsJSGlobalProxy()) { |
| 2693 Object* proto = GetPrototype(); | 2744 Object* proto = GetPrototype(); |
| 2694 if (proto->IsNull()) return result->NotFound(); | 2745 if (proto->IsNull()) return result->NotFound(); |
| 2695 ASSERT(proto->IsJSGlobalObject()); | 2746 ASSERT(proto->IsJSGlobalObject()); |
| 2696 return JSObject::cast(proto)->LocalLookup(name, result); | 2747 return JSObject::cast(proto)->LocalLookup(name, result); |
| 2697 } | 2748 } |
| 2698 | 2749 |
| 2699 // Do not use inline caching if the object is a non-global object | 2750 // Do not use inline caching if the object is a non-global object |
| 2700 // that requires access checks. | 2751 // that requires access checks. |
| 2701 if (!IsJSGlobalProxy() && IsAccessCheckNeeded()) { | 2752 if (!IsJSGlobalProxy() && IsAccessCheckNeeded()) { |
| 2702 result->DisallowCaching(); | 2753 result->DisallowCaching(); |
| 2703 } | 2754 } |
| 2704 | 2755 |
| 2705 Isolate* isolate = Isolate::Current(); | |
| 2706 | |
| 2707 // Check __proto__ before interceptor. | 2756 // Check __proto__ before interceptor. |
| 2708 if (name->Equals(isolate->heap()->Proto_symbol()) && | 2757 if (name->Equals(heap->Proto_symbol()) && |
| 2709 !IsJSContextExtensionObject()) { | 2758 !IsJSContextExtensionObject()) { |
| 2710 result->ConstantResult(this); | 2759 result->ConstantResult(this); |
| 2711 return; | 2760 return; |
| 2712 } | 2761 } |
| 2713 | 2762 |
| 2714 // Check for lookup interceptor except when bootstrapping. | 2763 // Check for lookup interceptor except when bootstrapping. |
| 2715 if (HasNamedInterceptor() && !isolate->bootstrapper()->IsActive()) { | 2764 if (HasNamedInterceptor() && !heap->isolate()->bootstrapper()->IsActive()) { |
| 2716 result->InterceptorResult(this); | 2765 result->InterceptorResult(this); |
| 2717 return; | 2766 return; |
| 2718 } | 2767 } |
| 2719 | 2768 |
| 2720 LocalLookupRealNamedProperty(name, result); | 2769 LocalLookupRealNamedProperty(name, result); |
| 2721 } | 2770 } |
| 2722 | 2771 |
| 2723 | 2772 |
| 2724 void JSObject::Lookup(String* name, LookupResult* result) { | 2773 void JSObject::Lookup(String* name, LookupResult* result) { |
| 2725 // Ecma-262 3rd 8.6.2.4 | 2774 // Ecma-262 3rd 8.6.2.4 |
| 2726 Heap* heap = HEAP; | 2775 Heap* heap = GetHeap(); |
| 2727 for (Object* current = this; | 2776 for (Object* current = this; |
| 2728 current != heap->null_value(); | 2777 current != heap->null_value(); |
| 2729 current = JSObject::cast(current)->GetPrototype()) { | 2778 current = JSObject::cast(current)->GetPrototype()) { |
| 2730 JSObject::cast(current)->LocalLookup(name, result); | 2779 JSObject::cast(current)->LocalLookup(name, result); |
| 2731 if (result->IsProperty()) return; | 2780 if (result->IsProperty()) return; |
| 2732 } | 2781 } |
| 2733 result->NotFound(); | 2782 result->NotFound(); |
| 2734 } | 2783 } |
| 2735 | 2784 |
| 2736 | 2785 |
| 2737 // Search object and it's prototype chain for callback properties. | 2786 // Search object and it's prototype chain for callback properties. |
| 2738 void JSObject::LookupCallback(String* name, LookupResult* result) { | 2787 void JSObject::LookupCallback(String* name, LookupResult* result) { |
| 2739 Heap* heap = HEAP; | 2788 Heap* heap = GetHeap(); |
| 2740 for (Object* current = this; | 2789 for (Object* current = this; |
| 2741 current != heap->null_value(); | 2790 current != heap->null_value(); |
| 2742 current = JSObject::cast(current)->GetPrototype()) { | 2791 current = JSObject::cast(current)->GetPrototype()) { |
| 2743 JSObject::cast(current)->LocalLookupRealNamedProperty(name, result); | 2792 JSObject::cast(current)->LocalLookupRealNamedProperty(name, result); |
| 2744 if (result->IsProperty() && result->type() == CALLBACKS) return; | 2793 if (result->IsProperty() && result->type() == CALLBACKS) return; |
| 2745 } | 2794 } |
| 2746 result->NotFound(); | 2795 result->NotFound(); |
| 2747 } | 2796 } |
| 2748 | 2797 |
| 2749 | 2798 |
| 2750 Object* JSObject::DefineGetterSetter(String* name, | 2799 Object* JSObject::DefineGetterSetter(String* name, |
| 2751 PropertyAttributes attributes) { | 2800 PropertyAttributes attributes) { |
| 2801 Heap* heap = GetHeap(); |
| 2802 |
| 2752 // Make sure that the top context does not change when doing callbacks or | 2803 // Make sure that the top context does not change when doing callbacks or |
| 2753 // interceptor calls. | 2804 // interceptor calls. |
| 2754 AssertNoContextChange ncc; | 2805 AssertNoContextChange ncc; |
| 2755 | 2806 |
| 2756 // Try to flatten before operating on the string. | 2807 // Try to flatten before operating on the string. |
| 2757 name->TryFlatten(); | 2808 name->TryFlatten(); |
| 2758 | 2809 |
| 2759 if (!CanSetCallback(name)) { | 2810 if (!CanSetCallback(name)) { |
| 2760 return HEAP->undefined_value(); | 2811 return heap->undefined_value(); |
| 2761 } | 2812 } |
| 2762 | 2813 |
| 2763 uint32_t index = 0; | 2814 uint32_t index = 0; |
| 2764 bool is_element = name->AsArrayIndex(&index); | 2815 bool is_element = name->AsArrayIndex(&index); |
| 2765 if (is_element && IsJSArray()) return HEAP->undefined_value(); | 2816 if (is_element && IsJSArray()) return heap->undefined_value(); |
| 2766 | 2817 |
| 2767 if (is_element) { | 2818 if (is_element) { |
| 2768 switch (GetElementsKind()) { | 2819 switch (GetElementsKind()) { |
| 2769 case FAST_ELEMENTS: | 2820 case FAST_ELEMENTS: |
| 2770 break; | 2821 break; |
| 2771 case PIXEL_ELEMENTS: | 2822 case PIXEL_ELEMENTS: |
| 2772 case EXTERNAL_BYTE_ELEMENTS: | 2823 case EXTERNAL_BYTE_ELEMENTS: |
| 2773 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 2824 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 2774 case EXTERNAL_SHORT_ELEMENTS: | 2825 case EXTERNAL_SHORT_ELEMENTS: |
| 2775 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 2826 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 2776 case EXTERNAL_INT_ELEMENTS: | 2827 case EXTERNAL_INT_ELEMENTS: |
| 2777 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 2828 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 2778 case EXTERNAL_FLOAT_ELEMENTS: | 2829 case EXTERNAL_FLOAT_ELEMENTS: |
| 2779 // Ignore getters and setters on pixel and external array | 2830 // Ignore getters and setters on pixel and external array |
| 2780 // elements. | 2831 // elements. |
| 2781 return HEAP->undefined_value(); | 2832 return heap->undefined_value(); |
| 2782 case DICTIONARY_ELEMENTS: { | 2833 case DICTIONARY_ELEMENTS: { |
| 2783 // Lookup the index. | 2834 // Lookup the index. |
| 2784 NumberDictionary* dictionary = element_dictionary(); | 2835 NumberDictionary* dictionary = element_dictionary(); |
| 2785 int entry = dictionary->FindEntry(index); | 2836 int entry = dictionary->FindEntry(index); |
| 2786 if (entry != NumberDictionary::kNotFound) { | 2837 if (entry != NumberDictionary::kNotFound) { |
| 2787 Object* result = dictionary->ValueAt(entry); | 2838 Object* result = dictionary->ValueAt(entry); |
| 2788 PropertyDetails details = dictionary->DetailsAt(entry); | 2839 PropertyDetails details = dictionary->DetailsAt(entry); |
| 2789 if (details.IsReadOnly()) return HEAP->undefined_value(); | 2840 if (details.IsReadOnly()) return heap->undefined_value(); |
| 2790 if (details.type() == CALLBACKS) { | 2841 if (details.type() == CALLBACKS) { |
| 2791 if (result->IsFixedArray()) { | 2842 if (result->IsFixedArray()) { |
| 2792 return result; | 2843 return result; |
| 2793 } | 2844 } |
| 2794 // Otherwise allow to override it. | 2845 // Otherwise allow to override it. |
| 2795 } | 2846 } |
| 2796 } | 2847 } |
| 2797 break; | 2848 break; |
| 2798 } | 2849 } |
| 2799 default: | 2850 default: |
| 2800 UNREACHABLE(); | 2851 UNREACHABLE(); |
| 2801 break; | 2852 break; |
| 2802 } | 2853 } |
| 2803 } else { | 2854 } else { |
| 2804 // Lookup the name. | 2855 // Lookup the name. |
| 2805 LookupResult result; | 2856 LookupResult result; |
| 2806 LocalLookup(name, &result); | 2857 LocalLookup(name, &result); |
| 2807 if (result.IsProperty()) { | 2858 if (result.IsProperty()) { |
| 2808 if (result.IsReadOnly()) return HEAP->undefined_value(); | 2859 if (result.IsReadOnly()) return heap->undefined_value(); |
| 2809 if (result.type() == CALLBACKS) { | 2860 if (result.type() == CALLBACKS) { |
| 2810 Object* obj = result.GetCallbackObject(); | 2861 Object* obj = result.GetCallbackObject(); |
| 2811 // Need to preserve old getters/setters. | 2862 // Need to preserve old getters/setters. |
| 2812 if (obj->IsFixedArray()) { | 2863 if (obj->IsFixedArray()) { |
| 2813 // Use set to update attributes. | 2864 // Use set to update attributes. |
| 2814 return SetPropertyCallback(name, obj, attributes); | 2865 return SetPropertyCallback(name, obj, attributes); |
| 2815 } | 2866 } |
| 2816 } | 2867 } |
| 2817 } | 2868 } |
| 2818 } | 2869 } |
| 2819 | 2870 |
| 2820 // Allocate the fixed array to hold getter and setter. | 2871 // Allocate the fixed array to hold getter and setter. |
| 2821 Object* structure = HEAP->AllocateFixedArray(2, TENURED); | 2872 Object* structure = heap->AllocateFixedArray(2, TENURED); |
| 2822 if (structure->IsFailure()) return structure; | 2873 if (structure->IsFailure()) return structure; |
| 2823 | 2874 |
| 2824 if (is_element) { | 2875 if (is_element) { |
| 2825 return SetElementCallback(index, structure, attributes); | 2876 return SetElementCallback(index, structure, attributes); |
| 2826 } else { | 2877 } else { |
| 2827 return SetPropertyCallback(name, structure, attributes); | 2878 return SetPropertyCallback(name, structure, attributes); |
| 2828 } | 2879 } |
| 2829 } | 2880 } |
| 2830 | 2881 |
| 2831 | 2882 |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2903 | 2954 |
| 2904 if (convert_back_to_fast) { | 2955 if (convert_back_to_fast) { |
| 2905 ok = TransformToFastProperties(0); | 2956 ok = TransformToFastProperties(0); |
| 2906 if (ok->IsFailure()) return ok; | 2957 if (ok->IsFailure()) return ok; |
| 2907 } | 2958 } |
| 2908 return result; | 2959 return result; |
| 2909 } | 2960 } |
| 2910 | 2961 |
| 2911 Object* JSObject::DefineAccessor(String* name, bool is_getter, JSFunction* fun, | 2962 Object* JSObject::DefineAccessor(String* name, bool is_getter, JSFunction* fun, |
| 2912 PropertyAttributes attributes) { | 2963 PropertyAttributes attributes) { |
| 2964 Heap* heap = GetHeap(); |
| 2965 |
| 2913 // Check access rights if needed. | 2966 // Check access rights if needed. |
| 2914 if (IsAccessCheckNeeded() && | 2967 if (IsAccessCheckNeeded() && |
| 2915 !Isolate::Current()->MayNamedAccess(this, name, v8::ACCESS_SET)) { | 2968 !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_SET)) { |
| 2916 Isolate::Current()->ReportFailedAccessCheck(this, v8::ACCESS_SET); | 2969 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET); |
| 2917 return HEAP->undefined_value(); | 2970 return heap->undefined_value(); |
| 2918 } | 2971 } |
| 2919 | 2972 |
| 2920 if (IsJSGlobalProxy()) { | 2973 if (IsJSGlobalProxy()) { |
| 2921 Object* proto = GetPrototype(); | 2974 Object* proto = GetPrototype(); |
| 2922 if (proto->IsNull()) return this; | 2975 if (proto->IsNull()) return this; |
| 2923 ASSERT(proto->IsJSGlobalObject()); | 2976 ASSERT(proto->IsJSGlobalObject()); |
| 2924 return JSObject::cast(proto)->DefineAccessor(name, is_getter, | 2977 return JSObject::cast(proto)->DefineAccessor(name, is_getter, |
| 2925 fun, attributes); | 2978 fun, attributes); |
| 2926 } | 2979 } |
| 2927 | 2980 |
| 2928 Object* array = DefineGetterSetter(name, attributes); | 2981 Object* array = DefineGetterSetter(name, attributes); |
| 2929 if (array->IsFailure() || array->IsUndefined()) return array; | 2982 if (array->IsFailure() || array->IsUndefined()) return array; |
| 2930 FixedArray::cast(array)->set(is_getter ? 0 : 1, fun); | 2983 FixedArray::cast(array)->set(is_getter ? 0 : 1, fun); |
| 2931 return this; | 2984 return this; |
| 2932 } | 2985 } |
| 2933 | 2986 |
| 2934 | 2987 |
| 2935 Object* JSObject::DefineAccessor(AccessorInfo* info) { | 2988 Object* JSObject::DefineAccessor(AccessorInfo* info) { |
| 2989 Heap* heap = GetHeap(); |
| 2990 |
| 2936 String* name = String::cast(info->name()); | 2991 String* name = String::cast(info->name()); |
| 2937 // Check access rights if needed. | 2992 // Check access rights if needed. |
| 2938 if (IsAccessCheckNeeded() && | 2993 if (IsAccessCheckNeeded() && |
| 2939 !Isolate::Current()->MayNamedAccess(this, name, v8::ACCESS_SET)) { | 2994 !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_SET)) { |
| 2940 Isolate::Current()->ReportFailedAccessCheck(this, v8::ACCESS_SET); | 2995 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET); |
| 2941 return HEAP->undefined_value(); | 2996 return heap->undefined_value(); |
| 2942 } | 2997 } |
| 2943 | 2998 |
| 2944 if (IsJSGlobalProxy()) { | 2999 if (IsJSGlobalProxy()) { |
| 2945 Object* proto = GetPrototype(); | 3000 Object* proto = GetPrototype(); |
| 2946 if (proto->IsNull()) return this; | 3001 if (proto->IsNull()) return this; |
| 2947 ASSERT(proto->IsJSGlobalObject()); | 3002 ASSERT(proto->IsJSGlobalObject()); |
| 2948 return JSObject::cast(proto)->DefineAccessor(info); | 3003 return JSObject::cast(proto)->DefineAccessor(info); |
| 2949 } | 3004 } |
| 2950 | 3005 |
| 2951 // Make sure that the top context does not change when doing callbacks or | 3006 // Make sure that the top context does not change when doing callbacks or |
| 2952 // interceptor calls. | 3007 // interceptor calls. |
| 2953 AssertNoContextChange ncc; | 3008 AssertNoContextChange ncc; |
| 2954 | 3009 |
| 2955 // Try to flatten before operating on the string. | 3010 // Try to flatten before operating on the string. |
| 2956 name->TryFlatten(); | 3011 name->TryFlatten(); |
| 2957 | 3012 |
| 2958 if (!CanSetCallback(name)) { | 3013 if (!CanSetCallback(name)) { |
| 2959 return HEAP->undefined_value(); | 3014 return heap->undefined_value(); |
| 2960 } | 3015 } |
| 2961 | 3016 |
| 2962 uint32_t index = 0; | 3017 uint32_t index = 0; |
| 2963 bool is_element = name->AsArrayIndex(&index); | 3018 bool is_element = name->AsArrayIndex(&index); |
| 2964 | 3019 |
| 2965 if (is_element) { | 3020 if (is_element) { |
| 2966 if (IsJSArray()) return HEAP->undefined_value(); | 3021 if (IsJSArray()) return heap->undefined_value(); |
| 2967 | 3022 |
| 2968 // Accessors overwrite previous callbacks (cf. with getters/setters). | 3023 // Accessors overwrite previous callbacks (cf. with getters/setters). |
| 2969 switch (GetElementsKind()) { | 3024 switch (GetElementsKind()) { |
| 2970 case FAST_ELEMENTS: | 3025 case FAST_ELEMENTS: |
| 2971 break; | 3026 break; |
| 2972 case PIXEL_ELEMENTS: | 3027 case PIXEL_ELEMENTS: |
| 2973 case EXTERNAL_BYTE_ELEMENTS: | 3028 case EXTERNAL_BYTE_ELEMENTS: |
| 2974 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: | 3029 case EXTERNAL_UNSIGNED_BYTE_ELEMENTS: |
| 2975 case EXTERNAL_SHORT_ELEMENTS: | 3030 case EXTERNAL_SHORT_ELEMENTS: |
| 2976 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: | 3031 case EXTERNAL_UNSIGNED_SHORT_ELEMENTS: |
| 2977 case EXTERNAL_INT_ELEMENTS: | 3032 case EXTERNAL_INT_ELEMENTS: |
| 2978 case EXTERNAL_UNSIGNED_INT_ELEMENTS: | 3033 case EXTERNAL_UNSIGNED_INT_ELEMENTS: |
| 2979 case EXTERNAL_FLOAT_ELEMENTS: | 3034 case EXTERNAL_FLOAT_ELEMENTS: |
| 2980 // Ignore getters and setters on pixel and external array | 3035 // Ignore getters and setters on pixel and external array |
| 2981 // elements. | 3036 // elements. |
| 2982 return HEAP->undefined_value(); | 3037 return heap->undefined_value(); |
| 2983 case DICTIONARY_ELEMENTS: | 3038 case DICTIONARY_ELEMENTS: |
| 2984 break; | 3039 break; |
| 2985 default: | 3040 default: |
| 2986 UNREACHABLE(); | 3041 UNREACHABLE(); |
| 2987 break; | 3042 break; |
| 2988 } | 3043 } |
| 2989 | 3044 |
| 2990 Object* ok = SetElementCallback(index, info, info->property_attributes()); | 3045 Object* ok = SetElementCallback(index, info, info->property_attributes()); |
| 2991 if (ok->IsFailure()) return ok; | 3046 if (ok->IsFailure()) return ok; |
| 2992 } else { | 3047 } else { |
| 2993 // Lookup the name. | 3048 // Lookup the name. |
| 2994 LookupResult result; | 3049 LookupResult result; |
| 2995 LocalLookup(name, &result); | 3050 LocalLookup(name, &result); |
| 2996 // ES5 forbids turning a property into an accessor if it's not | 3051 // ES5 forbids turning a property into an accessor if it's not |
| 2997 // configurable (that is IsDontDelete in ES3 and v8), see 8.6.1 (Table 5). | 3052 // configurable (that is IsDontDelete in ES3 and v8), see 8.6.1 (Table 5). |
| 2998 if (result.IsProperty() && (result.IsReadOnly() || result.IsDontDelete())) { | 3053 if (result.IsProperty() && (result.IsReadOnly() || result.IsDontDelete())) { |
| 2999 return HEAP->undefined_value(); | 3054 return heap->undefined_value(); |
| 3000 } | 3055 } |
| 3001 Object* ok = SetPropertyCallback(name, info, info->property_attributes()); | 3056 Object* ok = SetPropertyCallback(name, info, info->property_attributes()); |
| 3002 if (ok->IsFailure()) return ok; | 3057 if (ok->IsFailure()) return ok; |
| 3003 } | 3058 } |
| 3004 | 3059 |
| 3005 return this; | 3060 return this; |
| 3006 } | 3061 } |
| 3007 | 3062 |
| 3008 | 3063 |
| 3009 Object* JSObject::LookupAccessor(String* name, bool is_getter) { | 3064 Object* JSObject::LookupAccessor(String* name, bool is_getter) { |
| 3065 Heap* heap = GetHeap(); |
| 3066 |
| 3010 // Make sure that the top context does not change when doing callbacks or | 3067 // Make sure that the top context does not change when doing callbacks or |
| 3011 // interceptor calls. | 3068 // interceptor calls. |
| 3012 AssertNoContextChange ncc; | 3069 AssertNoContextChange ncc; |
| 3013 | 3070 |
| 3014 // Check access rights if needed. | 3071 // Check access rights if needed. |
| 3015 if (IsAccessCheckNeeded() && | 3072 if (IsAccessCheckNeeded() && |
| 3016 !Isolate::Current()->MayNamedAccess(this, name, v8::ACCESS_HAS)) { | 3073 !heap->isolate()->MayNamedAccess(this, name, v8::ACCESS_HAS)) { |
| 3017 Isolate::Current()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 3074 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 3018 return HEAP->undefined_value(); | 3075 return heap->undefined_value(); |
| 3019 } | 3076 } |
| 3020 | 3077 |
| 3021 // Make the lookup and include prototypes. | 3078 // Make the lookup and include prototypes. |
| 3022 int accessor_index = is_getter ? kGetterIndex : kSetterIndex; | 3079 int accessor_index = is_getter ? kGetterIndex : kSetterIndex; |
| 3023 uint32_t index = 0; | 3080 uint32_t index = 0; |
| 3024 Heap* heap = HEAP; | |
| 3025 if (name->AsArrayIndex(&index)) { | 3081 if (name->AsArrayIndex(&index)) { |
| 3026 for (Object* obj = this; | 3082 for (Object* obj = this; |
| 3027 obj != heap->null_value(); | 3083 obj != heap->null_value(); |
| 3028 obj = JSObject::cast(obj)->GetPrototype()) { | 3084 obj = JSObject::cast(obj)->GetPrototype()) { |
| 3029 JSObject* js_object = JSObject::cast(obj); | 3085 JSObject* js_object = JSObject::cast(obj); |
| 3030 if (js_object->HasDictionaryElements()) { | 3086 if (js_object->HasDictionaryElements()) { |
| 3031 NumberDictionary* dictionary = js_object->element_dictionary(); | 3087 NumberDictionary* dictionary = js_object->element_dictionary(); |
| 3032 int entry = dictionary->FindEntry(index); | 3088 int entry = dictionary->FindEntry(index); |
| 3033 if (entry != NumberDictionary::kNotFound) { | 3089 if (entry != NumberDictionary::kNotFound) { |
| 3034 Object* element = dictionary->ValueAt(entry); | 3090 Object* element = dictionary->ValueAt(entry); |
| 3035 PropertyDetails details = dictionary->DetailsAt(entry); | 3091 PropertyDetails details = dictionary->DetailsAt(entry); |
| 3036 if (details.type() == CALLBACKS) { | 3092 if (details.type() == CALLBACKS) { |
| 3037 if (element->IsFixedArray()) { | 3093 if (element->IsFixedArray()) { |
| 3038 return FixedArray::cast(element)->get(accessor_index); | 3094 return FixedArray::cast(element)->get(accessor_index); |
| 3039 } | 3095 } |
| 3040 } | 3096 } |
| 3041 } | 3097 } |
| 3042 } | 3098 } |
| 3043 } | 3099 } |
| 3044 } else { | 3100 } else { |
| 3045 for (Object* obj = this; | 3101 for (Object* obj = this; |
| 3046 obj != heap->null_value(); | 3102 obj != heap->null_value(); |
| 3047 obj = JSObject::cast(obj)->GetPrototype()) { | 3103 obj = JSObject::cast(obj)->GetPrototype()) { |
| 3048 LookupResult result; | 3104 LookupResult result; |
| 3049 JSObject::cast(obj)->LocalLookup(name, &result); | 3105 JSObject::cast(obj)->LocalLookup(name, &result); |
| 3050 if (result.IsProperty()) { | 3106 if (result.IsProperty()) { |
| 3051 if (result.IsReadOnly()) return HEAP->undefined_value(); | 3107 if (result.IsReadOnly()) return heap->undefined_value(); |
| 3052 if (result.type() == CALLBACKS) { | 3108 if (result.type() == CALLBACKS) { |
| 3053 Object* obj = result.GetCallbackObject(); | 3109 Object* obj = result.GetCallbackObject(); |
| 3054 if (obj->IsFixedArray()) { | 3110 if (obj->IsFixedArray()) { |
| 3055 return FixedArray::cast(obj)->get(accessor_index); | 3111 return FixedArray::cast(obj)->get(accessor_index); |
| 3056 } | 3112 } |
| 3057 } | 3113 } |
| 3058 } | 3114 } |
| 3059 } | 3115 } |
| 3060 } | 3116 } |
| 3061 return HEAP->undefined_value(); | 3117 return heap->undefined_value(); |
| 3062 } | 3118 } |
| 3063 | 3119 |
| 3064 | 3120 |
| 3065 Object* JSObject::SlowReverseLookup(Object* value) { | 3121 Object* JSObject::SlowReverseLookup(Object* value) { |
| 3122 Heap* heap = GetHeap(); |
| 3066 if (HasFastProperties()) { | 3123 if (HasFastProperties()) { |
| 3067 DescriptorArray* descs = map()->instance_descriptors(); | 3124 DescriptorArray* descs = map()->instance_descriptors(); |
| 3068 for (int i = 0; i < descs->number_of_descriptors(); i++) { | 3125 for (int i = 0; i < descs->number_of_descriptors(); i++) { |
| 3069 if (descs->GetType(i) == FIELD) { | 3126 if (descs->GetType(i) == FIELD) { |
| 3070 if (FastPropertyAt(descs->GetFieldIndex(i)) == value) { | 3127 if (FastPropertyAt(descs->GetFieldIndex(i)) == value) { |
| 3071 return descs->GetKey(i); | 3128 return descs->GetKey(i); |
| 3072 } | 3129 } |
| 3073 } else if (descs->GetType(i) == CONSTANT_FUNCTION) { | 3130 } else if (descs->GetType(i) == CONSTANT_FUNCTION) { |
| 3074 if (descs->GetConstantFunction(i) == value) { | 3131 if (descs->GetConstantFunction(i) == value) { |
| 3075 return descs->GetKey(i); | 3132 return descs->GetKey(i); |
| 3076 } | 3133 } |
| 3077 } | 3134 } |
| 3078 } | 3135 } |
| 3079 return HEAP->undefined_value(); | 3136 return heap->undefined_value(); |
| 3080 } else { | 3137 } else { |
| 3081 return property_dictionary()->SlowReverseLookup(value); | 3138 return property_dictionary()->SlowReverseLookup(value); |
| 3082 } | 3139 } |
| 3083 } | 3140 } |
| 3084 | 3141 |
| 3085 | 3142 |
| 3086 Object* Map::CopyDropDescriptors() { | 3143 Object* Map::CopyDropDescriptors() { |
| 3087 Object* result = GetHeap()->AllocateMap(instance_type(), instance_size()); | 3144 Heap* heap = GetHeap(); |
| 3145 Object* result = heap->AllocateMap(instance_type(), instance_size()); |
| 3088 if (result->IsFailure()) return result; | 3146 if (result->IsFailure()) return result; |
| 3089 Map::cast(result)->set_prototype(prototype()); | 3147 Map::cast(result)->set_prototype(prototype()); |
| 3090 Map::cast(result)->set_constructor(constructor()); | 3148 Map::cast(result)->set_constructor(constructor()); |
| 3091 // Don't copy descriptors, so map transitions always remain a forest. | 3149 // Don't copy descriptors, so map transitions always remain a forest. |
| 3092 // If we retained the same descriptors we would have two maps | 3150 // If we retained the same descriptors we would have two maps |
| 3093 // pointing to the same transition which is bad because the garbage | 3151 // pointing to the same transition which is bad because the garbage |
| 3094 // collector relies on being able to reverse pointers from transitions | 3152 // collector relies on being able to reverse pointers from transitions |
| 3095 // to maps. If properties need to be retained use CopyDropTransitions. | 3153 // to maps. If properties need to be retained use CopyDropTransitions. |
| 3096 Map::cast(result)->set_instance_descriptors( | 3154 Map::cast(result)->set_instance_descriptors( |
| 3097 GetHeap()->empty_descriptor_array()); | 3155 heap->empty_descriptor_array()); |
| 3098 // Please note instance_type and instance_size are set when allocated. | 3156 // Please note instance_type and instance_size are set when allocated. |
| 3099 Map::cast(result)->set_inobject_properties(inobject_properties()); | 3157 Map::cast(result)->set_inobject_properties(inobject_properties()); |
| 3100 Map::cast(result)->set_unused_property_fields(unused_property_fields()); | 3158 Map::cast(result)->set_unused_property_fields(unused_property_fields()); |
| 3101 | 3159 |
| 3102 // If the map has pre-allocated properties always start out with a descriptor | 3160 // If the map has pre-allocated properties always start out with a descriptor |
| 3103 // array describing these properties. | 3161 // array describing these properties. |
| 3104 if (pre_allocated_property_fields() > 0) { | 3162 if (pre_allocated_property_fields() > 0) { |
| 3105 ASSERT(constructor()->IsJSFunction()); | 3163 ASSERT(constructor()->IsJSFunction()); |
| 3106 JSFunction* ctor = JSFunction::cast(constructor()); | 3164 JSFunction* ctor = JSFunction::cast(constructor()); |
| 3107 Object* descriptors = | 3165 Object* descriptors = |
| 3108 ctor->initial_map()->instance_descriptors()->RemoveTransitions(); | 3166 ctor->initial_map()->instance_descriptors()->RemoveTransitions(); |
| 3109 if (descriptors->IsFailure()) return descriptors; | 3167 if (descriptors->IsFailure()) return descriptors; |
| 3110 Map::cast(result)->set_instance_descriptors( | 3168 Map::cast(result)->set_instance_descriptors( |
| 3111 DescriptorArray::cast(descriptors)); | 3169 DescriptorArray::cast(descriptors)); |
| 3112 Map::cast(result)->set_pre_allocated_property_fields( | 3170 Map::cast(result)->set_pre_allocated_property_fields( |
| 3113 pre_allocated_property_fields()); | 3171 pre_allocated_property_fields()); |
| 3114 } | 3172 } |
| 3115 Map::cast(result)->set_bit_field(bit_field()); | 3173 Map::cast(result)->set_bit_field(bit_field()); |
| 3116 Map::cast(result)->set_bit_field2(bit_field2()); | 3174 Map::cast(result)->set_bit_field2(bit_field2()); |
| 3117 Map::cast(result)->ClearCodeCache(GetHeap()); | 3175 Map::cast(result)->ClearCodeCache(heap); |
| 3118 return result; | 3176 return result; |
| 3119 } | 3177 } |
| 3120 | 3178 |
| 3121 | 3179 |
| 3122 Object* Map::CopyDropTransitions() { | 3180 Object* Map::CopyDropTransitions() { |
| 3123 Object* new_map = CopyDropDescriptors(); | 3181 Object* new_map = CopyDropDescriptors(); |
| 3124 if (new_map->IsFailure()) return new_map; | 3182 if (new_map->IsFailure()) return new_map; |
| 3125 Object* descriptors = instance_descriptors()->RemoveTransitions(); | 3183 Object* descriptors = instance_descriptors()->RemoveTransitions(); |
| 3126 if (descriptors->IsFailure()) return descriptors; | 3184 if (descriptors->IsFailure()) return descriptors; |
| 3127 cast(new_map)->set_instance_descriptors(DescriptorArray::cast(descriptors)); | 3185 cast(new_map)->set_instance_descriptors(DescriptorArray::cast(descriptors)); |
| 3128 return new_map; | 3186 return new_map; |
| 3129 } | 3187 } |
| 3130 | 3188 |
| 3131 | 3189 |
| 3132 Object* Map::UpdateCodeCache(String* name, Code* code) { | 3190 Object* Map::UpdateCodeCache(String* name, Code* code) { |
| 3133 // Allocate the code cache if not present. | 3191 // Allocate the code cache if not present. |
| 3134 if (code_cache()->IsFixedArray()) { | 3192 if (code_cache()->IsFixedArray()) { |
| 3135 Object* result = HEAP->AllocateCodeCache(); | 3193 Object* result = GetHeap()->AllocateCodeCache(); |
| 3136 if (result->IsFailure()) return result; | 3194 if (result->IsFailure()) return result; |
| 3137 set_code_cache(result); | 3195 set_code_cache(result); |
| 3138 } | 3196 } |
| 3139 | 3197 |
| 3140 // Update the code cache. | 3198 // Update the code cache. |
| 3141 return CodeCache::cast(code_cache())->Update(name, code); | 3199 return CodeCache::cast(code_cache())->Update(name, code); |
| 3142 } | 3200 } |
| 3143 | 3201 |
| 3144 | 3202 |
| 3145 Object* Map::FindInCodeCache(String* name, Code::Flags flags) { | 3203 Object* Map::FindInCodeCache(String* name, Code::Flags flags) { |
| 3146 // Do a lookup if a code cache exists. | 3204 // Do a lookup if a code cache exists. |
| 3147 if (!code_cache()->IsFixedArray()) { | 3205 if (!code_cache()->IsFixedArray()) { |
| 3148 return CodeCache::cast(code_cache())->Lookup(name, flags); | 3206 return CodeCache::cast(code_cache())->Lookup(name, flags); |
| 3149 } else { | 3207 } else { |
| 3150 return HEAP->undefined_value(); | 3208 return GetHeap()->undefined_value(); |
| 3151 } | 3209 } |
| 3152 } | 3210 } |
| 3153 | 3211 |
| 3154 | 3212 |
| 3155 int Map::IndexInCodeCache(Object* name, Code* code) { | 3213 int Map::IndexInCodeCache(Object* name, Code* code) { |
| 3156 // Get the internal index if a code cache exists. | 3214 // Get the internal index if a code cache exists. |
| 3157 if (!code_cache()->IsFixedArray()) { | 3215 if (!code_cache()->IsFixedArray()) { |
| 3158 return CodeCache::cast(code_cache())->GetIndex(name, code); | 3216 return CodeCache::cast(code_cache())->GetIndex(name, code); |
| 3159 } | 3217 } |
| 3160 return -1; | 3218 return -1; |
| (...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3262 Object* CodeCache::Lookup(String* name, Code::Flags flags) { | 3320 Object* CodeCache::Lookup(String* name, Code::Flags flags) { |
| 3263 if (Code::ExtractTypeFromFlags(flags) == NORMAL) { | 3321 if (Code::ExtractTypeFromFlags(flags) == NORMAL) { |
| 3264 return LookupNormalTypeCache(name, flags); | 3322 return LookupNormalTypeCache(name, flags); |
| 3265 } else { | 3323 } else { |
| 3266 return LookupDefaultCache(name, flags); | 3324 return LookupDefaultCache(name, flags); |
| 3267 } | 3325 } |
| 3268 } | 3326 } |
| 3269 | 3327 |
| 3270 | 3328 |
| 3271 Object* CodeCache::LookupDefaultCache(String* name, Code::Flags flags) { | 3329 Object* CodeCache::LookupDefaultCache(String* name, Code::Flags flags) { |
| 3330 Heap* heap = GetHeap(); |
| 3272 FixedArray* cache = default_cache(); | 3331 FixedArray* cache = default_cache(); |
| 3273 int length = cache->length(); | 3332 int length = cache->length(); |
| 3274 for (int i = 0; i < length; i += kCodeCacheEntrySize) { | 3333 for (int i = 0; i < length; i += kCodeCacheEntrySize) { |
| 3275 Object* key = cache->get(i + kCodeCacheEntryNameOffset); | 3334 Object* key = cache->get(i + kCodeCacheEntryNameOffset); |
| 3276 // Skip deleted elements. | 3335 // Skip deleted elements. |
| 3277 if (key->IsNull()) continue; | 3336 if (key->IsNull()) continue; |
| 3278 if (key->IsUndefined()) return key; | 3337 if (key->IsUndefined()) return key; |
| 3279 if (name->Equals(String::cast(key))) { | 3338 if (name->Equals(String::cast(key))) { |
| 3280 Code* code = Code::cast(cache->get(i + kCodeCacheEntryCodeOffset)); | 3339 Code* code = Code::cast(cache->get(i + kCodeCacheEntryCodeOffset)); |
| 3281 if (code->flags() == flags) { | 3340 if (code->flags() == flags) { |
| 3282 return code; | 3341 return code; |
| 3283 } | 3342 } |
| 3284 } | 3343 } |
| 3285 } | 3344 } |
| 3286 return HEAP->undefined_value(); | 3345 return heap->undefined_value(); |
| 3287 } | 3346 } |
| 3288 | 3347 |
| 3289 | 3348 |
| 3290 Object* CodeCache::LookupNormalTypeCache(String* name, Code::Flags flags) { | 3349 Object* CodeCache::LookupNormalTypeCache(String* name, Code::Flags flags) { |
| 3291 if (!normal_type_cache()->IsUndefined()) { | 3350 if (!normal_type_cache()->IsUndefined()) { |
| 3292 CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache()); | 3351 CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache()); |
| 3293 return cache->Lookup(name, flags); | 3352 return cache->Lookup(name, flags); |
| 3294 } else { | 3353 } else { |
| 3295 return HEAP->undefined_value(); | 3354 return GetHeap()->undefined_value(); |
| 3296 } | 3355 } |
| 3297 } | 3356 } |
| 3298 | 3357 |
| 3299 | 3358 |
| 3300 int CodeCache::GetIndex(Object* name, Code* code) { | 3359 int CodeCache::GetIndex(Object* name, Code* code) { |
| 3301 if (code->type() == NORMAL) { | 3360 if (code->type() == NORMAL) { |
| 3302 if (normal_type_cache()->IsUndefined()) return -1; | 3361 if (normal_type_cache()->IsUndefined()) return -1; |
| 3303 CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache()); | 3362 CodeCacheHashTable* cache = CodeCacheHashTable::cast(normal_type_cache()); |
| 3304 return cache->GetIndex(String::cast(name), code->flags()); | 3363 return cache->GetIndex(String::cast(name), code->flags()); |
| 3305 } | 3364 } |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3366 | 3425 |
| 3367 uint32_t HashForObject(Object* obj) { | 3426 uint32_t HashForObject(Object* obj) { |
| 3368 FixedArray* pair = FixedArray::cast(obj); | 3427 FixedArray* pair = FixedArray::cast(obj); |
| 3369 String* name = String::cast(pair->get(0)); | 3428 String* name = String::cast(pair->get(0)); |
| 3370 Code* code = Code::cast(pair->get(1)); | 3429 Code* code = Code::cast(pair->get(1)); |
| 3371 return NameFlagsHashHelper(name, code->flags()); | 3430 return NameFlagsHashHelper(name, code->flags()); |
| 3372 } | 3431 } |
| 3373 | 3432 |
| 3374 Object* AsObject() { | 3433 Object* AsObject() { |
| 3375 ASSERT(code_ != NULL); | 3434 ASSERT(code_ != NULL); |
| 3376 Object* obj = HEAP->AllocateFixedArray(2); | 3435 Object* obj = name_->GetHeap()->AllocateFixedArray(2); |
| 3377 if (obj->IsFailure()) return obj; | 3436 if (obj->IsFailure()) return obj; |
| 3378 FixedArray* pair = FixedArray::cast(obj); | 3437 FixedArray* pair = FixedArray::cast(obj); |
| 3379 pair->set(0, name_); | 3438 pair->set(0, name_); |
| 3380 pair->set(1, code_); | 3439 pair->set(1, code_); |
| 3381 return pair; | 3440 return pair; |
| 3382 } | 3441 } |
| 3383 | 3442 |
| 3384 private: | 3443 private: |
| 3385 String* name_; | 3444 String* name_; |
| 3386 Code::Flags flags_; | 3445 Code::Flags flags_; |
| 3387 Code* code_; | 3446 Code* code_; |
| 3388 }; | 3447 }; |
| 3389 | 3448 |
| 3390 | 3449 |
| 3391 Object* CodeCacheHashTable::Lookup(String* name, Code::Flags flags) { | 3450 Object* CodeCacheHashTable::Lookup(String* name, Code::Flags flags) { |
| 3392 CodeCacheHashTableKey key(name, flags); | 3451 CodeCacheHashTableKey key(name, flags); |
| 3393 int entry = FindEntry(&key); | 3452 int entry = FindEntry(&key); |
| 3394 if (entry == kNotFound) return HEAP->undefined_value(); | 3453 if (entry == kNotFound) return GetHeap()->undefined_value(); |
| 3395 return get(EntryToIndex(entry) + 1); | 3454 return get(EntryToIndex(entry) + 1); |
| 3396 } | 3455 } |
| 3397 | 3456 |
| 3398 | 3457 |
| 3399 Object* CodeCacheHashTable::Put(String* name, Code* code) { | 3458 Object* CodeCacheHashTable::Put(String* name, Code* code) { |
| 3400 CodeCacheHashTableKey key(name, code); | 3459 CodeCacheHashTableKey key(name, code); |
| 3401 Object* obj = EnsureCapacity(1, &key); | 3460 Object* obj = EnsureCapacity(1, &key); |
| 3402 if (obj->IsFailure()) return obj; | 3461 if (obj->IsFailure()) return obj; |
| 3403 | 3462 |
| 3404 // Don't use this, as the table might have grown. | 3463 // Don't use this, as the table might have grown. |
| (...skipping 12 matching lines...) Expand all Loading... |
| 3417 | 3476 |
| 3418 int CodeCacheHashTable::GetIndex(String* name, Code::Flags flags) { | 3477 int CodeCacheHashTable::GetIndex(String* name, Code::Flags flags) { |
| 3419 CodeCacheHashTableKey key(name, flags); | 3478 CodeCacheHashTableKey key(name, flags); |
| 3420 int entry = FindEntry(&key); | 3479 int entry = FindEntry(&key); |
| 3421 return (entry == kNotFound) ? -1 : entry; | 3480 return (entry == kNotFound) ? -1 : entry; |
| 3422 } | 3481 } |
| 3423 | 3482 |
| 3424 | 3483 |
| 3425 void CodeCacheHashTable::RemoveByIndex(int index) { | 3484 void CodeCacheHashTable::RemoveByIndex(int index) { |
| 3426 ASSERT(index >= 0); | 3485 ASSERT(index >= 0); |
| 3427 set(EntryToIndex(index), HEAP->null_value()); | 3486 Heap* heap = GetHeap(); |
| 3428 set(EntryToIndex(index) + 1, HEAP->null_value()); | 3487 set(EntryToIndex(index), heap->null_value()); |
| 3488 set(EntryToIndex(index) + 1, heap->null_value()); |
| 3429 ElementRemoved(); | 3489 ElementRemoved(); |
| 3430 } | 3490 } |
| 3431 | 3491 |
| 3432 | 3492 |
| 3433 void FixedArray::FixedArrayIterateBody(ObjectVisitor* v) { | 3493 void FixedArray::FixedArrayIterateBody(ObjectVisitor* v) { |
| 3434 IteratePointers(v, kHeaderSize, kHeaderSize + length() * kPointerSize); | 3494 IteratePointers(v, kHeaderSize, kHeaderSize + length() * kPointerSize); |
| 3435 } | 3495 } |
| 3436 | 3496 |
| 3437 | 3497 |
| 3438 static bool HasKey(FixedArray* array, Object* key) { | 3498 static bool HasKey(FixedArray* array, Object* key) { |
| 3439 int len0 = array->length(); | 3499 int len0 = array->length(); |
| 3440 for (int i = 0; i < len0; i++) { | 3500 for (int i = 0; i < len0; i++) { |
| 3441 Object* element = array->get(i); | 3501 Object* element = array->get(i); |
| 3442 if (element->IsSmi() && key->IsSmi() && (element == key)) return true; | 3502 if (element->IsSmi() && key->IsSmi() && (element == key)) return true; |
| 3443 if (element->IsString() && | 3503 if (element->IsString() && |
| 3444 key->IsString() && String::cast(element)->Equals(String::cast(key))) { | 3504 key->IsString() && String::cast(element)->Equals(String::cast(key))) { |
| 3445 return true; | 3505 return true; |
| 3446 } | 3506 } |
| 3447 } | 3507 } |
| 3448 return false; | 3508 return false; |
| 3449 } | 3509 } |
| 3450 | 3510 |
| 3451 | 3511 |
| 3452 Object* FixedArray::AddKeysFromJSArray(JSArray* array) { | 3512 Object* FixedArray::AddKeysFromJSArray(JSArray* array) { |
| 3513 Heap* heap = GetHeap(); |
| 3453 ASSERT(!array->HasPixelElements() && !array->HasExternalArrayElements()); | 3514 ASSERT(!array->HasPixelElements() && !array->HasExternalArrayElements()); |
| 3454 switch (array->GetElementsKind()) { | 3515 switch (array->GetElementsKind()) { |
| 3455 case JSObject::FAST_ELEMENTS: | 3516 case JSObject::FAST_ELEMENTS: |
| 3456 return UnionOfKeys(FixedArray::cast(array->elements())); | 3517 return UnionOfKeys(FixedArray::cast(array->elements())); |
| 3457 case JSObject::DICTIONARY_ELEMENTS: { | 3518 case JSObject::DICTIONARY_ELEMENTS: { |
| 3458 NumberDictionary* dict = array->element_dictionary(); | 3519 NumberDictionary* dict = array->element_dictionary(); |
| 3459 int size = dict->NumberOfElements(); | 3520 int size = dict->NumberOfElements(); |
| 3460 | 3521 |
| 3461 // Allocate a temporary fixed array. | 3522 // Allocate a temporary fixed array. |
| 3462 Object* object = HEAP->AllocateFixedArray(size); | 3523 Object* object = heap->AllocateFixedArray(size); |
| 3463 if (object->IsFailure()) return object; | 3524 if (object->IsFailure()) return object; |
| 3464 FixedArray* key_array = FixedArray::cast(object); | 3525 FixedArray* key_array = FixedArray::cast(object); |
| 3465 | 3526 |
| 3466 int capacity = dict->Capacity(); | 3527 int capacity = dict->Capacity(); |
| 3467 int pos = 0; | 3528 int pos = 0; |
| 3468 // Copy the elements from the JSArray to the temporary fixed array. | 3529 // Copy the elements from the JSArray to the temporary fixed array. |
| 3469 for (int i = 0; i < capacity; i++) { | 3530 for (int i = 0; i < capacity; i++) { |
| 3470 if (dict->IsKey(dict->KeyAt(i))) { | 3531 if (dict->IsKey(dict->KeyAt(i))) { |
| 3471 key_array->set(pos++, dict->ValueAt(i)); | 3532 key_array->set(pos++, dict->ValueAt(i)); |
| 3472 } | 3533 } |
| 3473 } | 3534 } |
| 3474 // Compute the union of this and the temporary fixed array. | 3535 // Compute the union of this and the temporary fixed array. |
| 3475 return UnionOfKeys(key_array); | 3536 return UnionOfKeys(key_array); |
| 3476 } | 3537 } |
| 3477 default: | 3538 default: |
| 3478 UNREACHABLE(); | 3539 UNREACHABLE(); |
| 3479 } | 3540 } |
| 3480 UNREACHABLE(); | 3541 UNREACHABLE(); |
| 3481 return HEAP->null_value(); // Failure case needs to "return" a value. | 3542 return heap->null_value(); // Failure case needs to "return" a value. |
| 3482 } | 3543 } |
| 3483 | 3544 |
| 3484 | 3545 |
| 3485 Object* FixedArray::UnionOfKeys(FixedArray* other) { | 3546 Object* FixedArray::UnionOfKeys(FixedArray* other) { |
| 3547 Heap* heap = GetHeap(); |
| 3486 int len0 = length(); | 3548 int len0 = length(); |
| 3487 int len1 = other->length(); | 3549 int len1 = other->length(); |
| 3488 // Optimize if either is empty. | 3550 // Optimize if either is empty. |
| 3489 if (len0 == 0) return other; | 3551 if (len0 == 0) return other; |
| 3490 if (len1 == 0) return this; | 3552 if (len1 == 0) return this; |
| 3491 | 3553 |
| 3492 // Compute how many elements are not in this. | 3554 // Compute how many elements are not in this. |
| 3493 int extra = 0; | 3555 int extra = 0; |
| 3494 for (int y = 0; y < len1; y++) { | 3556 for (int y = 0; y < len1; y++) { |
| 3495 Object* value = other->get(y); | 3557 Object* value = other->get(y); |
| 3496 if (!value->IsTheHole() && !HasKey(this, value)) extra++; | 3558 if (!value->IsTheHole() && !HasKey(this, value)) extra++; |
| 3497 } | 3559 } |
| 3498 | 3560 |
| 3499 if (extra == 0) return this; | 3561 if (extra == 0) return this; |
| 3500 | 3562 |
| 3501 // Allocate the result | 3563 // Allocate the result |
| 3502 Object* obj = HEAP->AllocateFixedArray(len0 + extra); | 3564 Object* obj = heap->AllocateFixedArray(len0 + extra); |
| 3503 if (obj->IsFailure()) return obj; | 3565 if (obj->IsFailure()) return obj; |
| 3504 // Fill in the content | 3566 // Fill in the content |
| 3505 AssertNoAllocation no_gc; | 3567 AssertNoAllocation no_gc; |
| 3506 FixedArray* result = FixedArray::cast(obj); | 3568 FixedArray* result = FixedArray::cast(obj); |
| 3507 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); | 3569 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); |
| 3508 for (int i = 0; i < len0; i++) { | 3570 for (int i = 0; i < len0; i++) { |
| 3509 result->set(i, get(i), mode); | 3571 result->set(i, get(i), mode); |
| 3510 } | 3572 } |
| 3511 // Fill in the extra keys. | 3573 // Fill in the extra keys. |
| 3512 int index = 0; | 3574 int index = 0; |
| 3513 for (int y = 0; y < len1; y++) { | 3575 for (int y = 0; y < len1; y++) { |
| 3514 Object* value = other->get(y); | 3576 Object* value = other->get(y); |
| 3515 if (!value->IsTheHole() && !HasKey(this, value)) { | 3577 if (!value->IsTheHole() && !HasKey(this, value)) { |
| 3516 result->set(len0 + index, other->get(y), mode); | 3578 result->set(len0 + index, other->get(y), mode); |
| 3517 index++; | 3579 index++; |
| 3518 } | 3580 } |
| 3519 } | 3581 } |
| 3520 ASSERT(extra == index); | 3582 ASSERT(extra == index); |
| 3521 return result; | 3583 return result; |
| 3522 } | 3584 } |
| 3523 | 3585 |
| 3524 | 3586 |
| 3525 Object* FixedArray::CopySize(int new_length) { | 3587 Object* FixedArray::CopySize(int new_length) { |
| 3526 if (new_length == 0) return HEAP->empty_fixed_array(); | 3588 Heap* heap = GetHeap(); |
| 3527 Object* obj = HEAP->AllocateFixedArray(new_length); | 3589 if (new_length == 0) return heap->empty_fixed_array(); |
| 3590 Object* obj = heap->AllocateFixedArray(new_length); |
| 3528 if (obj->IsFailure()) return obj; | 3591 if (obj->IsFailure()) return obj; |
| 3529 FixedArray* result = FixedArray::cast(obj); | 3592 FixedArray* result = FixedArray::cast(obj); |
| 3530 // Copy the content | 3593 // Copy the content |
| 3531 AssertNoAllocation no_gc; | 3594 AssertNoAllocation no_gc; |
| 3532 int len = length(); | 3595 int len = length(); |
| 3533 if (new_length < len) len = new_length; | 3596 if (new_length < len) len = new_length; |
| 3534 result->set_map(map()); | 3597 result->set_map(map()); |
| 3535 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); | 3598 WriteBarrierMode mode = result->GetWriteBarrierMode(no_gc); |
| 3536 for (int i = 0; i < len; i++) { | 3599 for (int i = 0; i < len; i++) { |
| 3537 result->set(i, get(i), mode); | 3600 result->set(i, get(i), mode); |
| (...skipping 16 matching lines...) Expand all Loading... |
| 3554 if (length() != other->length()) return false; | 3617 if (length() != other->length()) return false; |
| 3555 for (int i = 0 ; i < length(); ++i) { | 3618 for (int i = 0 ; i < length(); ++i) { |
| 3556 if (get(i) != other->get(i)) return false; | 3619 if (get(i) != other->get(i)) return false; |
| 3557 } | 3620 } |
| 3558 return true; | 3621 return true; |
| 3559 } | 3622 } |
| 3560 #endif | 3623 #endif |
| 3561 | 3624 |
| 3562 | 3625 |
| 3563 Object* DescriptorArray::Allocate(int number_of_descriptors) { | 3626 Object* DescriptorArray::Allocate(int number_of_descriptors) { |
| 3627 Heap* heap = Isolate::Current()->heap(); |
| 3564 if (number_of_descriptors == 0) { | 3628 if (number_of_descriptors == 0) { |
| 3565 return HEAP->empty_descriptor_array(); | 3629 return heap->empty_descriptor_array(); |
| 3566 } | 3630 } |
| 3567 // Allocate the array of keys. | 3631 // Allocate the array of keys. |
| 3568 Object* array = | 3632 Object* array = |
| 3569 HEAP->AllocateFixedArray(ToKeyIndex(number_of_descriptors)); | 3633 heap->AllocateFixedArray(ToKeyIndex(number_of_descriptors)); |
| 3570 if (array->IsFailure()) return array; | 3634 if (array->IsFailure()) return array; |
| 3571 // Do not use DescriptorArray::cast on incomplete object. | 3635 // Do not use DescriptorArray::cast on incomplete object. |
| 3572 FixedArray* result = FixedArray::cast(array); | 3636 FixedArray* result = FixedArray::cast(array); |
| 3573 | 3637 |
| 3574 // Allocate the content array and set it in the descriptor array. | 3638 // Allocate the content array and set it in the descriptor array. |
| 3575 array = HEAP->AllocateFixedArray(number_of_descriptors << 1); | 3639 array = heap->AllocateFixedArray(number_of_descriptors << 1); |
| 3576 if (array->IsFailure()) return array; | 3640 if (array->IsFailure()) return array; |
| 3577 result->set(kContentArrayIndex, array); | 3641 result->set(kContentArrayIndex, array); |
| 3578 result->set(kEnumerationIndexIndex, | 3642 result->set(kEnumerationIndexIndex, |
| 3579 Smi::FromInt(PropertyDetails::kInitialIndex)); | 3643 Smi::FromInt(PropertyDetails::kInitialIndex)); |
| 3580 return result; | 3644 return result; |
| 3581 } | 3645 } |
| 3582 | 3646 |
| 3583 | 3647 |
| 3584 void DescriptorArray::SetEnumCache(FixedArray* bridge_storage, | 3648 void DescriptorArray::SetEnumCache(FixedArray* bridge_storage, |
| 3585 FixedArray* new_cache) { | 3649 FixedArray* new_cache) { |
| (...skipping 249 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3835 if (length() != other->length()) return false; | 3899 if (length() != other->length()) return false; |
| 3836 for (int i = 0; i < length(); ++i) { | 3900 for (int i = 0; i < length(); ++i) { |
| 3837 if (get(i) != other->get(i) && i != kContentArrayIndex) return false; | 3901 if (get(i) != other->get(i) && i != kContentArrayIndex) return false; |
| 3838 } | 3902 } |
| 3839 return GetContentArray()->IsEqualTo(other->GetContentArray()); | 3903 return GetContentArray()->IsEqualTo(other->GetContentArray()); |
| 3840 } | 3904 } |
| 3841 #endif | 3905 #endif |
| 3842 | 3906 |
| 3843 | 3907 |
| 3844 bool String::LooksValid() { | 3908 bool String::LooksValid() { |
| 3845 if (!HEAP->Contains(this)) return false; | 3909 if (!GetHeap()->Contains(this)) return false; |
| 3846 return true; | 3910 return true; |
| 3847 } | 3911 } |
| 3848 | 3912 |
| 3849 | 3913 |
| 3850 int String::Utf8Length() { | 3914 int String::Utf8Length() { |
| 3851 if (IsAsciiRepresentation()) return length(); | 3915 if (IsAsciiRepresentation()) return length(); |
| 3852 // Attempt to flatten before accessing the string. It probably | 3916 // Attempt to flatten before accessing the string. It probably |
| 3853 // doesn't make Utf8Length faster, but it is very likely that | 3917 // doesn't make Utf8Length faster, but it is very likely that |
| 3854 // the string will be accessed later (for example by WriteUtf8) | 3918 // the string will be accessed later (for example by WriteUtf8) |
| 3855 // so it's still a good idea. | 3919 // so it's still a good idea. |
| 3920 Heap* heap = GetHeap(); |
| 3856 TryFlatten(); | 3921 TryFlatten(); |
| 3857 Access<StringInputBuffer> buffer( | 3922 Access<StringInputBuffer> buffer( |
| 3858 Isolate::Current()->objects_string_input_buffer()); | 3923 heap->isolate()->objects_string_input_buffer()); |
| 3859 buffer->Reset(0, this); | 3924 buffer->Reset(0, this); |
| 3860 int result = 0; | 3925 int result = 0; |
| 3861 while (buffer->has_more()) | 3926 while (buffer->has_more()) |
| 3862 result += unibrow::Utf8::Length(buffer->GetNext()); | 3927 result += unibrow::Utf8::Length(buffer->GetNext()); |
| 3863 return result; | 3928 return result; |
| 3864 } | 3929 } |
| 3865 | 3930 |
| 3866 | 3931 |
| 3867 Vector<const char> String::ToAsciiVector() { | 3932 Vector<const char> String::ToAsciiVector() { |
| 3868 ASSERT(IsAsciiRepresentation()); | 3933 ASSERT(IsAsciiRepresentation()); |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3915 return Vector<const uc16>(start + offset, length); | 3980 return Vector<const uc16>(start + offset, length); |
| 3916 } | 3981 } |
| 3917 | 3982 |
| 3918 | 3983 |
| 3919 SmartPointer<char> String::ToCString(AllowNullsFlag allow_nulls, | 3984 SmartPointer<char> String::ToCString(AllowNullsFlag allow_nulls, |
| 3920 RobustnessFlag robust_flag, | 3985 RobustnessFlag robust_flag, |
| 3921 int offset, | 3986 int offset, |
| 3922 int length, | 3987 int length, |
| 3923 int* length_return) { | 3988 int* length_return) { |
| 3924 ASSERT(NativeAllocationChecker::allocation_allowed()); | 3989 ASSERT(NativeAllocationChecker::allocation_allowed()); |
| 3990 Heap* heap = GetHeap(); |
| 3925 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) { | 3991 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) { |
| 3926 return SmartPointer<char>(NULL); | 3992 return SmartPointer<char>(NULL); |
| 3927 } | 3993 } |
| 3928 | 3994 |
| 3929 // Negative length means the to the end of the string. | 3995 // Negative length means the to the end of the string. |
| 3930 if (length < 0) length = kMaxInt - offset; | 3996 if (length < 0) length = kMaxInt - offset; |
| 3931 | 3997 |
| 3932 // Compute the size of the UTF-8 string. Start at the specified offset. | 3998 // Compute the size of the UTF-8 string. Start at the specified offset. |
| 3933 Access<StringInputBuffer> buffer( | 3999 Access<StringInputBuffer> buffer( |
| 3934 Isolate::Current()->objects_string_input_buffer()); | 4000 heap->isolate()->objects_string_input_buffer()); |
| 3935 buffer->Reset(offset, this); | 4001 buffer->Reset(offset, this); |
| 3936 int character_position = offset; | 4002 int character_position = offset; |
| 3937 int utf8_bytes = 0; | 4003 int utf8_bytes = 0; |
| 3938 while (buffer->has_more()) { | 4004 while (buffer->has_more()) { |
| 3939 uint16_t character = buffer->GetNext(); | 4005 uint16_t character = buffer->GetNext(); |
| 3940 if (character_position < offset + length) { | 4006 if (character_position < offset + length) { |
| 3941 utf8_bytes += unibrow::Utf8::Length(character); | 4007 utf8_bytes += unibrow::Utf8::Length(character); |
| 3942 } | 4008 } |
| 3943 character_position++; | 4009 character_position++; |
| 3944 } | 4010 } |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3993 case kConsStringTag: | 4059 case kConsStringTag: |
| 3994 UNREACHABLE(); | 4060 UNREACHABLE(); |
| 3995 return NULL; | 4061 return NULL; |
| 3996 } | 4062 } |
| 3997 UNREACHABLE(); | 4063 UNREACHABLE(); |
| 3998 return NULL; | 4064 return NULL; |
| 3999 } | 4065 } |
| 4000 | 4066 |
| 4001 | 4067 |
| 4002 SmartPointer<uc16> String::ToWideCString(RobustnessFlag robust_flag) { | 4068 SmartPointer<uc16> String::ToWideCString(RobustnessFlag robust_flag) { |
| 4069 Heap* heap = GetHeap(); |
| 4003 ASSERT(NativeAllocationChecker::allocation_allowed()); | 4070 ASSERT(NativeAllocationChecker::allocation_allowed()); |
| 4004 | 4071 |
| 4005 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) { | 4072 if (robust_flag == ROBUST_STRING_TRAVERSAL && !LooksValid()) { |
| 4006 return SmartPointer<uc16>(); | 4073 return SmartPointer<uc16>(); |
| 4007 } | 4074 } |
| 4008 | 4075 |
| 4009 Access<StringInputBuffer> buffer( | 4076 Access<StringInputBuffer> buffer( |
| 4010 Isolate::Current()->objects_string_input_buffer()); | 4077 heap->isolate()->objects_string_input_buffer()); |
| 4011 buffer->Reset(this); | 4078 buffer->Reset(this); |
| 4012 | 4079 |
| 4013 uc16* result = NewArray<uc16>(length() + 1); | 4080 uc16* result = NewArray<uc16>(length() + 1); |
| 4014 | 4081 |
| 4015 int i = 0; | 4082 int i = 0; |
| 4016 while (buffer->has_more()) { | 4083 while (buffer->has_more()) { |
| 4017 uint16_t character = buffer->GetNext(); | 4084 uint16_t character = buffer->GetNext(); |
| 4018 result[i++] = character; | 4085 result[i++] = character; |
| 4019 } | 4086 } |
| 4020 result[i] = 0; | 4087 result[i] = 0; |
| (...skipping 704 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4725 } | 4792 } |
| 4726 } else { | 4793 } else { |
| 4727 isolate->objects_string_compare_buffer_b()->Reset(0, b); | 4794 isolate->objects_string_compare_buffer_b()->Reset(0, b); |
| 4728 return CompareStringContents(ia, | 4795 return CompareStringContents(ia, |
| 4729 isolate->objects_string_compare_buffer_b()); | 4796 isolate->objects_string_compare_buffer_b()); |
| 4730 } | 4797 } |
| 4731 } | 4798 } |
| 4732 | 4799 |
| 4733 | 4800 |
| 4734 bool String::SlowEquals(String* other) { | 4801 bool String::SlowEquals(String* other) { |
| 4802 Heap* heap = GetHeap(); |
| 4803 |
| 4735 // Fast check: negative check with lengths. | 4804 // Fast check: negative check with lengths. |
| 4736 int len = length(); | 4805 int len = length(); |
| 4737 if (len != other->length()) return false; | 4806 if (len != other->length()) return false; |
| 4738 if (len == 0) return true; | 4807 if (len == 0) return true; |
| 4739 | 4808 |
| 4740 // Fast check: if hash code is computed for both strings | 4809 // Fast check: if hash code is computed for both strings |
| 4741 // a fast negative check can be performed. | 4810 // a fast negative check can be performed. |
| 4742 if (HasHashCode() && other->HasHashCode()) { | 4811 if (HasHashCode() && other->HasHashCode()) { |
| 4743 if (Hash() != other->Hash()) return false; | 4812 if (Hash() != other->Hash()) return false; |
| 4744 } | 4813 } |
| 4745 | 4814 |
| 4746 // We know the strings are both non-empty. Compare the first chars | 4815 // We know the strings are both non-empty. Compare the first chars |
| 4747 // before we try to flatten the strings. | 4816 // before we try to flatten the strings. |
| 4748 if (this->Get(0) != other->Get(0)) return false; | 4817 if (this->Get(0) != other->Get(0)) return false; |
| 4749 | 4818 |
| 4750 String* lhs = this->TryFlattenGetString(); | 4819 String* lhs = this->TryFlattenGetString(); |
| 4751 String* rhs = other->TryFlattenGetString(); | 4820 String* rhs = other->TryFlattenGetString(); |
| 4752 | 4821 |
| 4753 if (StringShape(lhs).IsSequentialAscii() && | 4822 if (StringShape(lhs).IsSequentialAscii() && |
| 4754 StringShape(rhs).IsSequentialAscii()) { | 4823 StringShape(rhs).IsSequentialAscii()) { |
| 4755 const char* str1 = SeqAsciiString::cast(lhs)->GetChars(); | 4824 const char* str1 = SeqAsciiString::cast(lhs)->GetChars(); |
| 4756 const char* str2 = SeqAsciiString::cast(rhs)->GetChars(); | 4825 const char* str2 = SeqAsciiString::cast(rhs)->GetChars(); |
| 4757 return CompareRawStringContents(Vector<const char>(str1, len), | 4826 return CompareRawStringContents(Vector<const char>(str1, len), |
| 4758 Vector<const char>(str2, len)); | 4827 Vector<const char>(str2, len)); |
| 4759 } | 4828 } |
| 4760 | 4829 |
| 4761 Isolate* isolate = Isolate::Current(); | 4830 Isolate* isolate = heap->isolate(); |
| 4762 if (lhs->IsFlat()) { | 4831 if (lhs->IsFlat()) { |
| 4763 if (lhs->IsAsciiRepresentation()) { | 4832 if (lhs->IsAsciiRepresentation()) { |
| 4764 Vector<const char> vec1 = lhs->ToAsciiVector(); | 4833 Vector<const char> vec1 = lhs->ToAsciiVector(); |
| 4765 if (rhs->IsFlat()) { | 4834 if (rhs->IsFlat()) { |
| 4766 if (rhs->IsAsciiRepresentation()) { | 4835 if (rhs->IsAsciiRepresentation()) { |
| 4767 Vector<const char> vec2 = rhs->ToAsciiVector(); | 4836 Vector<const char> vec2 = rhs->ToAsciiVector(); |
| 4768 return CompareRawStringContents(vec1, vec2); | 4837 return CompareRawStringContents(vec1, vec2); |
| 4769 } else { | 4838 } else { |
| 4770 VectorIterator<char> buf1(vec1); | 4839 VectorIterator<char> buf1(vec1); |
| 4771 VectorIterator<uc16> ib(rhs->ToUC16Vector()); | 4840 VectorIterator<uc16> ib(rhs->ToUC16Vector()); |
| (...skipping 28 matching lines...) Expand all Loading... |
| 4800 return CompareStringContentsPartial(isolate, | 4869 return CompareStringContentsPartial(isolate, |
| 4801 isolate->objects_string_compare_buffer_a(), rhs); | 4870 isolate->objects_string_compare_buffer_a(), rhs); |
| 4802 } | 4871 } |
| 4803 } | 4872 } |
| 4804 | 4873 |
| 4805 | 4874 |
| 4806 bool String::MarkAsUndetectable() { | 4875 bool String::MarkAsUndetectable() { |
| 4807 if (StringShape(this).IsSymbol()) return false; | 4876 if (StringShape(this).IsSymbol()) return false; |
| 4808 | 4877 |
| 4809 Map* map = this->map(); | 4878 Map* map = this->map(); |
| 4810 if (map == HEAP->string_map()) { | 4879 Heap* heap = map->GetHeap(); |
| 4811 this->set_map(HEAP->undetectable_string_map()); | 4880 if (map == heap->string_map()) { |
| 4881 this->set_map(heap->undetectable_string_map()); |
| 4812 return true; | 4882 return true; |
| 4813 } else if (map == HEAP->ascii_string_map()) { | 4883 } else if (map == heap->ascii_string_map()) { |
| 4814 this->set_map(HEAP->undetectable_ascii_string_map()); | 4884 this->set_map(heap->undetectable_ascii_string_map()); |
| 4815 return true; | 4885 return true; |
| 4816 } | 4886 } |
| 4817 // Rest cannot be marked as undetectable | 4887 // Rest cannot be marked as undetectable |
| 4818 return false; | 4888 return false; |
| 4819 } | 4889 } |
| 4820 | 4890 |
| 4821 | 4891 |
| 4822 bool String::IsEqualTo(Vector<const char> str) { | 4892 bool String::IsEqualTo(Vector<const char> str) { |
| 4893 Heap* heap = GetHeap(); |
| 4823 int slen = length(); | 4894 int slen = length(); |
| 4824 Access<Scanner::Utf8Decoder> decoder(Isolate::Current()-> | 4895 Access<Scanner::Utf8Decoder> decoder(heap->isolate()-> |
| 4825 scanner_character_classes()->utf8_decoder()); | 4896 scanner_character_classes()->utf8_decoder()); |
| 4826 decoder->Reset(str.start(), str.length()); | 4897 decoder->Reset(str.start(), str.length()); |
| 4827 int i; | 4898 int i; |
| 4828 for (i = 0; i < slen && decoder->has_more(); i++) { | 4899 for (i = 0; i < slen && decoder->has_more(); i++) { |
| 4829 uc32 r = decoder->GetNext(); | 4900 uc32 r = decoder->GetNext(); |
| 4830 if (Get(i) != r) return false; | 4901 if (Get(i) != r) return false; |
| 4831 } | 4902 } |
| 4832 return i == slen && !decoder->has_more(); | 4903 return i == slen && !decoder->has_more(); |
| 4833 } | 4904 } |
| 4834 | 4905 |
| (...skipping 144 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 4979 // index. | 5050 // index. |
| 4980 while (buffer->has_more()) { | 5051 while (buffer->has_more()) { |
| 4981 hasher.AddCharacterNoIndex(buffer->GetNext()); | 5052 hasher.AddCharacterNoIndex(buffer->GetNext()); |
| 4982 } | 5053 } |
| 4983 | 5054 |
| 4984 return hasher.GetHashField(); | 5055 return hasher.GetHashField(); |
| 4985 } | 5056 } |
| 4986 | 5057 |
| 4987 | 5058 |
| 4988 Object* String::SubString(int start, int end, PretenureFlag pretenure) { | 5059 Object* String::SubString(int start, int end, PretenureFlag pretenure) { |
| 5060 Heap* heap = GetHeap(); |
| 4989 if (start == 0 && end == length()) return this; | 5061 if (start == 0 && end == length()) return this; |
| 4990 Object* result = HEAP->AllocateSubString(this, start, end, pretenure); | 5062 Object* result = heap->AllocateSubString(this, start, end, pretenure); |
| 4991 return result; | 5063 return result; |
| 4992 } | 5064 } |
| 4993 | 5065 |
| 4994 | 5066 |
| 4995 void String::PrintOn(FILE* file) { | 5067 void String::PrintOn(FILE* file) { |
| 4996 int length = this->length(); | 5068 int length = this->length(); |
| 4997 for (int i = 0; i < length; i++) { | 5069 for (int i = 0; i < length; i++) { |
| 4998 fprintf(file, "%c", Get(i)); | 5070 fprintf(file, "%c", Get(i)); |
| 4999 } | 5071 } |
| 5000 } | 5072 } |
| (...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5062 | 5134 |
| 5063 | 5135 |
| 5064 void Map::MapIterateBody(ObjectVisitor* v) { | 5136 void Map::MapIterateBody(ObjectVisitor* v) { |
| 5065 // Assumes all Object* members are contiguously allocated! | 5137 // Assumes all Object* members are contiguously allocated! |
| 5066 IteratePointers(v, kPointerFieldsBeginOffset, kPointerFieldsEndOffset); | 5138 IteratePointers(v, kPointerFieldsBeginOffset, kPointerFieldsEndOffset); |
| 5067 } | 5139 } |
| 5068 | 5140 |
| 5069 | 5141 |
| 5070 Object* JSFunction::SetInstancePrototype(Object* value) { | 5142 Object* JSFunction::SetInstancePrototype(Object* value) { |
| 5071 ASSERT(value->IsJSObject()); | 5143 ASSERT(value->IsJSObject()); |
| 5072 | 5144 Heap* heap = GetHeap(); |
| 5073 if (has_initial_map()) { | 5145 if (has_initial_map()) { |
| 5074 initial_map()->set_prototype(value); | 5146 initial_map()->set_prototype(value); |
| 5075 } else { | 5147 } else { |
| 5076 // Put the value in the initial map field until an initial map is | 5148 // Put the value in the initial map field until an initial map is |
| 5077 // needed. At that point, a new initial map is created and the | 5149 // needed. At that point, a new initial map is created and the |
| 5078 // prototype is put into the initial map where it belongs. | 5150 // prototype is put into the initial map where it belongs. |
| 5079 set_prototype_or_initial_map(value); | 5151 set_prototype_or_initial_map(value); |
| 5080 } | 5152 } |
| 5081 HEAP->ClearInstanceofCache(); | 5153 heap->ClearInstanceofCache(); |
| 5082 return value; | 5154 return value; |
| 5083 } | 5155 } |
| 5084 | 5156 |
| 5085 | 5157 |
| 5086 | 5158 |
| 5087 Object* JSFunction::SetPrototype(Object* value) { | 5159 Object* JSFunction::SetPrototype(Object* value) { |
| 5088 ASSERT(should_have_prototype()); | 5160 ASSERT(should_have_prototype()); |
| 5089 Object* construct_prototype = value; | 5161 Object* construct_prototype = value; |
| 5090 | 5162 |
| 5091 // If the value is not a JSObject, store the value in the map's | 5163 // If the value is not a JSObject, store the value in the map's |
| 5092 // constructor field so it can be accessed. Also, set the prototype | 5164 // constructor field so it can be accessed. Also, set the prototype |
| 5093 // used for constructing objects to the original object prototype. | 5165 // used for constructing objects to the original object prototype. |
| 5094 // See ECMA-262 13.2.2. | 5166 // See ECMA-262 13.2.2. |
| 5095 if (!value->IsJSObject()) { | 5167 if (!value->IsJSObject()) { |
| 5168 Heap* heap = GetHeap(); |
| 5096 // Copy the map so this does not affect unrelated functions. | 5169 // Copy the map so this does not affect unrelated functions. |
| 5097 // Remove map transitions because they point to maps with a | 5170 // Remove map transitions because they point to maps with a |
| 5098 // different prototype. | 5171 // different prototype. |
| 5099 Object* new_map = map()->CopyDropTransitions(); | 5172 Object* new_map = map()->CopyDropTransitions(); |
| 5100 if (new_map->IsFailure()) return new_map; | 5173 if (new_map->IsFailure()) return new_map; |
| 5101 set_map(Map::cast(new_map)); | 5174 set_map(Map::cast(new_map)); |
| 5102 map()->set_constructor(value); | 5175 map()->set_constructor(value); |
| 5103 map()->set_non_instance_prototype(true); | 5176 map()->set_non_instance_prototype(true); |
| 5104 construct_prototype = | 5177 construct_prototype = |
| 5105 Isolate::Current()->context()->global_context()-> | 5178 heap->isolate()->context()->global_context()-> |
| 5106 initial_object_prototype(); | 5179 initial_object_prototype(); |
| 5107 } else { | 5180 } else { |
| 5108 map()->set_non_instance_prototype(false); | 5181 map()->set_non_instance_prototype(false); |
| 5109 } | 5182 } |
| 5110 | 5183 |
| 5111 return SetInstancePrototype(construct_prototype); | 5184 return SetInstancePrototype(construct_prototype); |
| 5112 } | 5185 } |
| 5113 | 5186 |
| 5114 | 5187 |
| 5115 Object* JSFunction::RemovePrototype() { | 5188 Object* JSFunction::RemovePrototype() { |
| 5116 ASSERT(map() == context()->global_context()->function_map()); | 5189 ASSERT(map() == context()->global_context()->function_map()); |
| 5190 Heap* heap = GetHeap(); |
| 5117 set_map(context()->global_context()->function_without_prototype_map()); | 5191 set_map(context()->global_context()->function_without_prototype_map()); |
| 5118 set_prototype_or_initial_map(HEAP->the_hole_value()); | 5192 set_prototype_or_initial_map(heap->the_hole_value()); |
| 5119 return this; | 5193 return this; |
| 5120 } | 5194 } |
| 5121 | 5195 |
| 5122 | 5196 |
| 5123 Object* JSFunction::SetInstanceClassName(String* name) { | 5197 Object* JSFunction::SetInstanceClassName(String* name) { |
| 5124 shared()->set_instance_class_name(name); | 5198 shared()->set_instance_class_name(name); |
| 5125 return this; | 5199 return this; |
| 5126 } | 5200 } |
| 5127 | 5201 |
| 5128 | 5202 |
| 5129 Context* JSFunction::GlobalContextFromLiterals(FixedArray* literals) { | 5203 Context* JSFunction::GlobalContextFromLiterals(FixedArray* literals) { |
| 5130 return Context::cast(literals->get(JSFunction::kLiteralGlobalContextIndex)); | 5204 return Context::cast(literals->get(JSFunction::kLiteralGlobalContextIndex)); |
| 5131 } | 5205 } |
| 5132 | 5206 |
| 5133 | 5207 |
| 5134 void Oddball::OddballIterateBody(ObjectVisitor* v) { | 5208 void Oddball::OddballIterateBody(ObjectVisitor* v) { |
| 5135 // Assumes all Object* members are contiguously allocated! | 5209 // Assumes all Object* members are contiguously allocated! |
| 5136 IteratePointers(v, kToStringOffset, kToNumberOffset + kPointerSize); | 5210 IteratePointers(v, kToStringOffset, kToNumberOffset + kPointerSize); |
| 5137 } | 5211 } |
| 5138 | 5212 |
| 5139 | 5213 |
| 5140 Object* Oddball::Initialize(const char* to_string, | 5214 Object* Oddball::Initialize(const char* to_string, |
| 5141 Object* to_number, | 5215 Object* to_number, |
| 5142 byte kind) { | 5216 byte kind) { |
| 5143 Object* symbol = HEAP->LookupAsciiSymbol(to_string); | 5217 Object* symbol = Isolate::Current()->heap()->LookupAsciiSymbol(to_string); |
| 5144 if (symbol->IsFailure()) return symbol; | 5218 if (symbol->IsFailure()) return symbol; |
| 5145 set_to_string(String::cast(symbol)); | 5219 set_to_string(String::cast(symbol)); |
| 5146 set_to_number(to_number); | 5220 set_to_number(to_number); |
| 5147 set_kind(kind); | 5221 set_kind(kind); |
| 5148 return this; | 5222 return this; |
| 5149 } | 5223 } |
| 5150 | 5224 |
| 5151 | 5225 |
| 5152 bool SharedFunctionInfo::HasSourceCode() { | 5226 bool SharedFunctionInfo::HasSourceCode() { |
| 5153 return !script()->IsUndefined() && | 5227 return !script()->IsUndefined() && |
| 5154 !Script::cast(script())->source()->IsUndefined(); | 5228 !Script::cast(script())->source()->IsUndefined(); |
| 5155 } | 5229 } |
| 5156 | 5230 |
| 5157 | 5231 |
| 5158 Object* SharedFunctionInfo::GetSourceCode() { | 5232 Object* SharedFunctionInfo::GetSourceCode() { |
| 5233 Heap* heap = GetHeap(); |
| 5159 HandleScope scope; | 5234 HandleScope scope; |
| 5160 if (script()->IsUndefined()) return HEAP->undefined_value(); | 5235 if (script()->IsUndefined()) return heap->undefined_value(); |
| 5161 Object* source = Script::cast(script())->source(); | 5236 Object* source = Script::cast(script())->source(); |
| 5162 if (source->IsUndefined()) return HEAP->undefined_value(); | 5237 if (source->IsUndefined()) return heap->undefined_value(); |
| 5163 return *SubString(Handle<String>(String::cast(source)), | 5238 return *SubString(Handle<String>(String::cast(source)), |
| 5164 start_position(), end_position()); | 5239 start_position(), end_position()); |
| 5165 } | 5240 } |
| 5166 | 5241 |
| 5167 | 5242 |
| 5168 int SharedFunctionInfo::CalculateInstanceSize() { | 5243 int SharedFunctionInfo::CalculateInstanceSize() { |
| 5169 int instance_size = | 5244 int instance_size = |
| 5170 JSObject::kHeaderSize + | 5245 JSObject::kHeaderSize + |
| 5171 expected_nof_properties() * kPointerSize; | 5246 expected_nof_properties() * kPointerSize; |
| 5172 if (instance_size > JSObject::kMaxInstanceSize) { | 5247 if (instance_size > JSObject::kMaxInstanceSize) { |
| 5173 instance_size = JSObject::kMaxInstanceSize; | 5248 instance_size = JSObject::kMaxInstanceSize; |
| 5174 } | 5249 } |
| 5175 return instance_size; | 5250 return instance_size; |
| 5176 } | 5251 } |
| 5177 | 5252 |
| 5178 | 5253 |
| 5179 int SharedFunctionInfo::CalculateInObjectProperties() { | 5254 int SharedFunctionInfo::CalculateInObjectProperties() { |
| 5180 return (CalculateInstanceSize() - JSObject::kHeaderSize) / kPointerSize; | 5255 return (CalculateInstanceSize() - JSObject::kHeaderSize) / kPointerSize; |
| 5181 } | 5256 } |
| 5182 | 5257 |
| 5183 | 5258 |
| 5184 bool SharedFunctionInfo::CanGenerateInlineConstructor(Object* prototype) { | 5259 bool SharedFunctionInfo::CanGenerateInlineConstructor(Object* prototype) { |
| 5260 Heap* heap = GetHeap(); |
| 5261 |
| 5185 // Check the basic conditions for generating inline constructor code. | 5262 // Check the basic conditions for generating inline constructor code. |
| 5186 if (!FLAG_inline_new | 5263 if (!FLAG_inline_new |
| 5187 || !has_only_simple_this_property_assignments() | 5264 || !has_only_simple_this_property_assignments() |
| 5188 || this_property_assignments_count() == 0) { | 5265 || this_property_assignments_count() == 0) { |
| 5189 return false; | 5266 return false; |
| 5190 } | 5267 } |
| 5191 | 5268 |
| 5192 // If the prototype is null inline constructors cause no problems. | 5269 // If the prototype is null inline constructors cause no problems. |
| 5193 if (!prototype->IsJSObject()) { | 5270 if (!prototype->IsJSObject()) { |
| 5194 ASSERT(prototype->IsNull()); | 5271 ASSERT(prototype->IsNull()); |
| 5195 return true; | 5272 return true; |
| 5196 } | 5273 } |
| 5197 | 5274 |
| 5198 // Traverse the proposed prototype chain looking for setters for properties of | 5275 // Traverse the proposed prototype chain looking for setters for properties of |
| 5199 // the same names as are set by the inline constructor. | 5276 // the same names as are set by the inline constructor. |
| 5200 Heap* heap = HEAP; | |
| 5201 for (Object* obj = prototype; | 5277 for (Object* obj = prototype; |
| 5202 obj != heap->null_value(); | 5278 obj != heap->null_value(); |
| 5203 obj = obj->GetPrototype()) { | 5279 obj = obj->GetPrototype()) { |
| 5204 JSObject* js_object = JSObject::cast(obj); | 5280 JSObject* js_object = JSObject::cast(obj); |
| 5205 for (int i = 0; i < this_property_assignments_count(); i++) { | 5281 for (int i = 0; i < this_property_assignments_count(); i++) { |
| 5206 LookupResult result; | 5282 LookupResult result; |
| 5207 String* name = GetThisPropertyAssignmentName(i); | 5283 String* name = GetThisPropertyAssignmentName(i); |
| 5208 js_object->LocalLookupRealNamedProperty(name, &result); | 5284 js_object->LocalLookupRealNamedProperty(name, &result); |
| 5209 if (result.IsProperty() && result.type() == CALLBACKS) { | 5285 if (result.IsProperty() && result.type() == CALLBACKS) { |
| 5210 return false; | 5286 return false; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 5221 FixedArray* assignments) { | 5297 FixedArray* assignments) { |
| 5222 set_compiler_hints(BooleanBit::set(compiler_hints(), | 5298 set_compiler_hints(BooleanBit::set(compiler_hints(), |
| 5223 kHasOnlySimpleThisPropertyAssignments, | 5299 kHasOnlySimpleThisPropertyAssignments, |
| 5224 only_simple_this_property_assignments)); | 5300 only_simple_this_property_assignments)); |
| 5225 set_this_property_assignments(assignments); | 5301 set_this_property_assignments(assignments); |
| 5226 set_this_property_assignments_count(assignments->length() / 3); | 5302 set_this_property_assignments_count(assignments->length() / 3); |
| 5227 } | 5303 } |
| 5228 | 5304 |
| 5229 | 5305 |
| 5230 void SharedFunctionInfo::ClearThisPropertyAssignmentsInfo() { | 5306 void SharedFunctionInfo::ClearThisPropertyAssignmentsInfo() { |
| 5307 Heap* heap = GetHeap(); |
| 5231 set_compiler_hints(BooleanBit::set(compiler_hints(), | 5308 set_compiler_hints(BooleanBit::set(compiler_hints(), |
| 5232 kHasOnlySimpleThisPropertyAssignments, | 5309 kHasOnlySimpleThisPropertyAssignments, |
| 5233 false)); | 5310 false)); |
| 5234 set_this_property_assignments(HEAP->undefined_value()); | 5311 set_this_property_assignments(heap->undefined_value()); |
| 5235 set_this_property_assignments_count(0); | 5312 set_this_property_assignments_count(0); |
| 5236 } | 5313 } |
| 5237 | 5314 |
| 5238 | 5315 |
| 5239 String* SharedFunctionInfo::GetThisPropertyAssignmentName(int index) { | 5316 String* SharedFunctionInfo::GetThisPropertyAssignmentName(int index) { |
| 5240 Object* obj = this_property_assignments(); | 5317 Object* obj = this_property_assignments(); |
| 5241 ASSERT(obj->IsFixedArray()); | 5318 ASSERT(obj->IsFixedArray()); |
| 5242 ASSERT(index < this_property_assignments_count()); | 5319 ASSERT(index < this_property_assignments_count()); |
| 5243 obj = FixedArray::cast(obj)->get(index * 3); | 5320 obj = FixedArray::cast(obj)->get(index * 3); |
| 5244 ASSERT(obj->IsString()); | 5321 ASSERT(obj->IsString()); |
| (...skipping 285 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5530 | 5607 |
| 5531 PrintF("RelocInfo (size = %d)\n", relocation_size()); | 5608 PrintF("RelocInfo (size = %d)\n", relocation_size()); |
| 5532 for (RelocIterator it(this); !it.done(); it.next()) | 5609 for (RelocIterator it(this); !it.done(); it.next()) |
| 5533 it.rinfo()->Print(); | 5610 it.rinfo()->Print(); |
| 5534 PrintF("\n"); | 5611 PrintF("\n"); |
| 5535 } | 5612 } |
| 5536 #endif // ENABLE_DISASSEMBLER | 5613 #endif // ENABLE_DISASSEMBLER |
| 5537 | 5614 |
| 5538 | 5615 |
| 5539 Object* JSObject::SetFastElementsCapacityAndLength(int capacity, int length) { | 5616 Object* JSObject::SetFastElementsCapacityAndLength(int capacity, int length) { |
| 5617 Heap* heap = GetHeap(); |
| 5618 |
| 5540 // We should never end in here with a pixel or external array. | 5619 // We should never end in here with a pixel or external array. |
| 5541 ASSERT(!HasPixelElements() && !HasExternalArrayElements()); | 5620 ASSERT(!HasPixelElements() && !HasExternalArrayElements()); |
| 5542 | 5621 |
| 5543 Object* obj = HEAP->AllocateFixedArrayWithHoles(capacity); | 5622 Object* obj = heap->AllocateFixedArrayWithHoles(capacity); |
| 5544 if (obj->IsFailure()) return obj; | 5623 if (obj->IsFailure()) return obj; |
| 5545 FixedArray* elems = FixedArray::cast(obj); | 5624 FixedArray* elems = FixedArray::cast(obj); |
| 5546 | 5625 |
| 5547 obj = map()->GetFastElementsMap(); | 5626 obj = map()->GetFastElementsMap(); |
| 5548 if (obj->IsFailure()) return obj; | 5627 if (obj->IsFailure()) return obj; |
| 5549 Map* new_map = Map::cast(obj); | 5628 Map* new_map = Map::cast(obj); |
| 5550 | 5629 |
| 5551 AssertNoAllocation no_gc; | 5630 AssertNoAllocation no_gc; |
| 5552 WriteBarrierMode mode = elems->GetWriteBarrierMode(no_gc); | 5631 WriteBarrierMode mode = elems->GetWriteBarrierMode(no_gc); |
| 5553 switch (GetElementsKind()) { | 5632 switch (GetElementsKind()) { |
| (...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5616 } | 5695 } |
| 5617 default: | 5696 default: |
| 5618 UNREACHABLE(); | 5697 UNREACHABLE(); |
| 5619 break; | 5698 break; |
| 5620 } | 5699 } |
| 5621 return this; | 5700 return this; |
| 5622 } | 5701 } |
| 5623 | 5702 |
| 5624 | 5703 |
| 5625 Object* JSArray::Initialize(int capacity) { | 5704 Object* JSArray::Initialize(int capacity) { |
| 5705 Heap* heap = GetHeap(); |
| 5706 |
| 5626 ASSERT(capacity >= 0); | 5707 ASSERT(capacity >= 0); |
| 5627 set_length(Smi::FromInt(0)); | 5708 set_length(Smi::FromInt(0)); |
| 5628 FixedArray* new_elements; | 5709 FixedArray* new_elements; |
| 5629 if (capacity == 0) { | 5710 if (capacity == 0) { |
| 5630 new_elements = HEAP->empty_fixed_array(); | 5711 new_elements = heap->empty_fixed_array(); |
| 5631 } else { | 5712 } else { |
| 5632 Object* obj = HEAP->AllocateFixedArrayWithHoles(capacity); | 5713 Object* obj = heap->AllocateFixedArrayWithHoles(capacity); |
| 5633 if (obj->IsFailure()) return obj; | 5714 if (obj->IsFailure()) return obj; |
| 5634 new_elements = FixedArray::cast(obj); | 5715 new_elements = FixedArray::cast(obj); |
| 5635 } | 5716 } |
| 5636 set_elements(new_elements); | 5717 set_elements(new_elements); |
| 5637 return this; | 5718 return this; |
| 5638 } | 5719 } |
| 5639 | 5720 |
| 5640 | 5721 |
| 5641 void JSArray::Expand(int required_size) { | 5722 void JSArray::Expand(int required_size) { |
| 5642 Handle<JSArray> self(this); | 5723 Handle<JSArray> self(this); |
| 5643 Handle<FixedArray> old_backing(FixedArray::cast(elements())); | 5724 Handle<FixedArray> old_backing(FixedArray::cast(elements())); |
| 5644 int old_size = old_backing->length(); | 5725 int old_size = old_backing->length(); |
| 5645 int new_size = required_size > old_size ? required_size : old_size; | 5726 int new_size = required_size > old_size ? required_size : old_size; |
| 5646 Handle<FixedArray> new_backing = Factory::NewFixedArray(new_size); | 5727 Handle<FixedArray> new_backing = Factory::NewFixedArray(new_size); |
| 5647 // Can't use this any more now because we may have had a GC! | 5728 // Can't use this any more now because we may have had a GC! |
| 5648 for (int i = 0; i < old_size; i++) new_backing->set(i, old_backing->get(i)); | 5729 for (int i = 0; i < old_size; i++) new_backing->set(i, old_backing->get(i)); |
| 5649 self->SetContent(*new_backing); | 5730 self->SetContent(*new_backing); |
| 5650 } | 5731 } |
| 5651 | 5732 |
| 5652 | 5733 |
| 5653 // Computes the new capacity when expanding the elements of a JSObject. | 5734 // Computes the new capacity when expanding the elements of a JSObject. |
| 5654 static int NewElementsCapacity(int old_capacity) { | 5735 static int NewElementsCapacity(int old_capacity) { |
| 5655 // (old_capacity + 50%) + 16 | 5736 // (old_capacity + 50%) + 16 |
| 5656 return old_capacity + (old_capacity >> 1) + 16; | 5737 return old_capacity + (old_capacity >> 1) + 16; |
| 5657 } | 5738 } |
| 5658 | 5739 |
| 5659 | 5740 |
| 5660 static Object* ArrayLengthRangeError() { | 5741 static Object* ArrayLengthRangeError(Heap* heap) { |
| 5661 HandleScope scope; | 5742 HandleScope scope; |
| 5662 return Isolate::Current()->Throw( | 5743 return heap->isolate()->Throw( |
| 5663 *Factory::NewRangeError("invalid_array_length", | 5744 *Factory::NewRangeError("invalid_array_length", |
| 5664 HandleVector<Object>(NULL, 0))); | 5745 HandleVector<Object>(NULL, 0))); |
| 5665 } | 5746 } |
| 5666 | 5747 |
| 5667 | 5748 |
| 5668 Object* JSObject::SetElementsLength(Object* len) { | 5749 Object* JSObject::SetElementsLength(Object* len) { |
| 5750 Heap* heap = GetHeap(); |
| 5751 |
| 5669 // We should never end in here with a pixel or external array. | 5752 // We should never end in here with a pixel or external array. |
| 5670 ASSERT(AllowsSetElementsLength()); | 5753 ASSERT(AllowsSetElementsLength()); |
| 5671 | 5754 |
| 5672 Object* smi_length = len->ToSmi(); | 5755 Object* smi_length = len->ToSmi(); |
| 5673 if (smi_length->IsSmi()) { | 5756 if (smi_length->IsSmi()) { |
| 5674 const int value = Smi::cast(smi_length)->value(); | 5757 const int value = Smi::cast(smi_length)->value(); |
| 5675 if (value < 0) return ArrayLengthRangeError(); | 5758 if (value < 0) return ArrayLengthRangeError(heap); |
| 5676 switch (GetElementsKind()) { | 5759 switch (GetElementsKind()) { |
| 5677 case FAST_ELEMENTS: { | 5760 case FAST_ELEMENTS: { |
| 5678 int old_capacity = FixedArray::cast(elements())->length(); | 5761 int old_capacity = FixedArray::cast(elements())->length(); |
| 5679 if (value <= old_capacity) { | 5762 if (value <= old_capacity) { |
| 5680 if (IsJSArray()) { | 5763 if (IsJSArray()) { |
| 5681 int old_length = FastD2I(JSArray::cast(this)->length()->Number()); | 5764 int old_length = FastD2I(JSArray::cast(this)->length()->Number()); |
| 5682 // NOTE: We may be able to optimize this by removing the | 5765 // NOTE: We may be able to optimize this by removing the |
| 5683 // last part of the elements backing storage array and | 5766 // last part of the elements backing storage array and |
| 5684 // setting the capacity to the new size. | 5767 // setting the capacity to the new size. |
| 5685 for (int i = value; i < old_length; i++) { | 5768 for (int i = value; i < old_length; i++) { |
| (...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5722 break; | 5805 break; |
| 5723 } | 5806 } |
| 5724 } | 5807 } |
| 5725 | 5808 |
| 5726 // General slow case. | 5809 // General slow case. |
| 5727 if (len->IsNumber()) { | 5810 if (len->IsNumber()) { |
| 5728 uint32_t length; | 5811 uint32_t length; |
| 5729 if (len->ToArrayIndex(&length)) { | 5812 if (len->ToArrayIndex(&length)) { |
| 5730 return SetSlowElements(len); | 5813 return SetSlowElements(len); |
| 5731 } else { | 5814 } else { |
| 5732 return ArrayLengthRangeError(); | 5815 return ArrayLengthRangeError(heap); |
| 5733 } | 5816 } |
| 5734 } | 5817 } |
| 5735 | 5818 |
| 5736 // len is not a number so make the array size one and | 5819 // len is not a number so make the array size one and |
| 5737 // set only element to len. | 5820 // set only element to len. |
| 5738 Object* obj = HEAP->AllocateFixedArray(1); | 5821 Object* obj = heap->AllocateFixedArray(1); |
| 5739 if (obj->IsFailure()) return obj; | 5822 if (obj->IsFailure()) return obj; |
| 5740 FixedArray::cast(obj)->set(0, len); | 5823 FixedArray::cast(obj)->set(0, len); |
| 5741 if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(1)); | 5824 if (IsJSArray()) JSArray::cast(this)->set_length(Smi::FromInt(1)); |
| 5742 set_elements(FixedArray::cast(obj)); | 5825 set_elements(FixedArray::cast(obj)); |
| 5743 return this; | 5826 return this; |
| 5744 } | 5827 } |
| 5745 | 5828 |
| 5746 | 5829 |
| 5747 Object* JSObject::SetPrototype(Object* value, | 5830 Object* JSObject::SetPrototype(Object* value, |
| 5748 bool skip_hidden_prototypes) { | 5831 bool skip_hidden_prototypes) { |
| 5832 Heap* heap = GetHeap(); |
| 5833 |
| 5749 // Silently ignore the change if value is not a JSObject or null. | 5834 // Silently ignore the change if value is not a JSObject or null. |
| 5750 // SpiderMonkey behaves this way. | 5835 // SpiderMonkey behaves this way. |
| 5751 if (!value->IsJSObject() && !value->IsNull()) return value; | 5836 if (!value->IsJSObject() && !value->IsNull()) return value; |
| 5752 | 5837 |
| 5753 // Before we can set the prototype we need to be sure | 5838 // Before we can set the prototype we need to be sure |
| 5754 // prototype cycles are prevented. | 5839 // prototype cycles are prevented. |
| 5755 // It is sufficient to validate that the receiver is not in the new prototype | 5840 // It is sufficient to validate that the receiver is not in the new prototype |
| 5756 // chain. | 5841 // chain. |
| 5757 Heap* heap = HEAP; | |
| 5758 for (Object* pt = value; pt != heap->null_value(); pt = pt->GetPrototype()) { | 5842 for (Object* pt = value; pt != heap->null_value(); pt = pt->GetPrototype()) { |
| 5759 if (JSObject::cast(pt) == this) { | 5843 if (JSObject::cast(pt) == this) { |
| 5760 // Cycle detected. | 5844 // Cycle detected. |
| 5761 HandleScope scope; | 5845 HandleScope scope; |
| 5762 return Isolate::Current()->Throw( | 5846 return heap->isolate()->Throw( |
| 5763 *Factory::NewError("cyclic_proto", HandleVector<Object>(NULL, 0))); | 5847 *Factory::NewError("cyclic_proto", HandleVector<Object>(NULL, 0))); |
| 5764 } | 5848 } |
| 5765 } | 5849 } |
| 5766 | 5850 |
| 5767 JSObject* real_receiver = this; | 5851 JSObject* real_receiver = this; |
| 5768 | 5852 |
| 5769 if (skip_hidden_prototypes) { | 5853 if (skip_hidden_prototypes) { |
| 5770 // Find the first object in the chain whose prototype object is not | 5854 // Find the first object in the chain whose prototype object is not |
| 5771 // hidden and set the new prototype on that object. | 5855 // hidden and set the new prototype on that object. |
| 5772 Object* current_proto = real_receiver->GetPrototype(); | 5856 Object* current_proto = real_receiver->GetPrototype(); |
| 5773 while (current_proto->IsJSObject() && | 5857 while (current_proto->IsJSObject() && |
| 5774 JSObject::cast(current_proto)->map()->is_hidden_prototype()) { | 5858 JSObject::cast(current_proto)->map()->is_hidden_prototype()) { |
| 5775 real_receiver = JSObject::cast(current_proto); | 5859 real_receiver = JSObject::cast(current_proto); |
| 5776 current_proto = current_proto->GetPrototype(); | 5860 current_proto = current_proto->GetPrototype(); |
| 5777 } | 5861 } |
| 5778 } | 5862 } |
| 5779 | 5863 |
| 5780 // Set the new prototype of the object. | 5864 // Set the new prototype of the object. |
| 5781 Object* new_map = real_receiver->map()->CopyDropTransitions(); | 5865 Object* new_map = real_receiver->map()->CopyDropTransitions(); |
| 5782 if (new_map->IsFailure()) return new_map; | 5866 if (new_map->IsFailure()) return new_map; |
| 5783 Map::cast(new_map)->set_prototype(value); | 5867 Map::cast(new_map)->set_prototype(value); |
| 5784 real_receiver->set_map(Map::cast(new_map)); | 5868 real_receiver->set_map(Map::cast(new_map)); |
| 5785 | 5869 |
| 5786 HEAP->ClearInstanceofCache(); | 5870 heap->ClearInstanceofCache(); |
| 5787 | 5871 |
| 5788 return value; | 5872 return value; |
| 5789 } | 5873 } |
| 5790 | 5874 |
| 5791 | 5875 |
| 5792 bool JSObject::HasElementPostInterceptor(JSObject* receiver, uint32_t index) { | 5876 bool JSObject::HasElementPostInterceptor(JSObject* receiver, uint32_t index) { |
| 5793 switch (GetElementsKind()) { | 5877 switch (GetElementsKind()) { |
| 5794 case FAST_ELEMENTS: { | 5878 case FAST_ELEMENTS: { |
| 5795 uint32_t length = IsJSArray() ? | 5879 uint32_t length = IsJSArray() ? |
| 5796 static_cast<uint32_t> | 5880 static_cast<uint32_t> |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 5876 VMState state(EXTERNAL); | 5960 VMState state(EXTERNAL); |
| 5877 result = getter(index, info); | 5961 result = getter(index, info); |
| 5878 } | 5962 } |
| 5879 if (!result.IsEmpty()) return true; | 5963 if (!result.IsEmpty()) return true; |
| 5880 } | 5964 } |
| 5881 return holder_handle->HasElementPostInterceptor(*receiver_handle, index); | 5965 return holder_handle->HasElementPostInterceptor(*receiver_handle, index); |
| 5882 } | 5966 } |
| 5883 | 5967 |
| 5884 | 5968 |
| 5885 bool JSObject::HasLocalElement(uint32_t index) { | 5969 bool JSObject::HasLocalElement(uint32_t index) { |
| 5970 Heap* heap = GetHeap(); |
| 5971 |
| 5886 // Check access rights if needed. | 5972 // Check access rights if needed. |
| 5887 if (IsAccessCheckNeeded() && | 5973 if (IsAccessCheckNeeded() && |
| 5888 !Isolate::Current()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { | 5974 !heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { |
| 5889 Isolate::Current()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 5975 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 5890 return false; | 5976 return false; |
| 5891 } | 5977 } |
| 5892 | 5978 |
| 5893 // Check for lookup interceptor | 5979 // Check for lookup interceptor |
| 5894 if (HasIndexedInterceptor()) { | 5980 if (HasIndexedInterceptor()) { |
| 5895 return HasElementWithInterceptor(this, index); | 5981 return HasElementWithInterceptor(this, index); |
| 5896 } | 5982 } |
| 5897 | 5983 |
| 5898 // Handle [] on String objects. | 5984 // Handle [] on String objects. |
| 5899 if (this->IsStringObjectWithCharacterAt(index)) return true; | 5985 if (this->IsStringObjectWithCharacterAt(index)) return true; |
| (...skipping 23 matching lines...) Expand all Loading... |
| 5923 } | 6009 } |
| 5924 case DICTIONARY_ELEMENTS: { | 6010 case DICTIONARY_ELEMENTS: { |
| 5925 return element_dictionary()->FindEntry(index) | 6011 return element_dictionary()->FindEntry(index) |
| 5926 != NumberDictionary::kNotFound; | 6012 != NumberDictionary::kNotFound; |
| 5927 } | 6013 } |
| 5928 default: | 6014 default: |
| 5929 UNREACHABLE(); | 6015 UNREACHABLE(); |
| 5930 break; | 6016 break; |
| 5931 } | 6017 } |
| 5932 UNREACHABLE(); | 6018 UNREACHABLE(); |
| 5933 return HEAP->null_value(); | 6019 return heap->null_value(); |
| 5934 } | 6020 } |
| 5935 | 6021 |
| 5936 | 6022 |
| 5937 bool JSObject::HasElementWithReceiver(JSObject* receiver, uint32_t index) { | 6023 bool JSObject::HasElementWithReceiver(JSObject* receiver, uint32_t index) { |
| 6024 Heap* heap = GetHeap(); |
| 6025 |
| 5938 // Check access rights if needed. | 6026 // Check access rights if needed. |
| 5939 if (IsAccessCheckNeeded() && | 6027 if (IsAccessCheckNeeded() && |
| 5940 !Isolate::Current()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { | 6028 !heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { |
| 5941 Isolate::Current()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 6029 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 5942 return false; | 6030 return false; |
| 5943 } | 6031 } |
| 5944 | 6032 |
| 5945 // Check for lookup interceptor | 6033 // Check for lookup interceptor |
| 5946 if (HasIndexedInterceptor()) { | 6034 if (HasIndexedInterceptor()) { |
| 5947 return HasElementWithInterceptor(receiver, index); | 6035 return HasElementWithInterceptor(receiver, index); |
| 5948 } | 6036 } |
| 5949 | 6037 |
| 5950 switch (GetElementsKind()) { | 6038 switch (GetElementsKind()) { |
| 5951 case FAST_ELEMENTS: { | 6039 case FAST_ELEMENTS: { |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6025 this_handle->SetElementWithoutInterceptor(index, *value_handle); | 6113 this_handle->SetElementWithoutInterceptor(index, *value_handle); |
| 6026 RETURN_IF_SCHEDULED_EXCEPTION(); | 6114 RETURN_IF_SCHEDULED_EXCEPTION(); |
| 6027 return raw_result; | 6115 return raw_result; |
| 6028 } | 6116 } |
| 6029 | 6117 |
| 6030 | 6118 |
| 6031 Object* JSObject::GetElementWithCallback(Object* receiver, | 6119 Object* JSObject::GetElementWithCallback(Object* receiver, |
| 6032 Object* structure, | 6120 Object* structure, |
| 6033 uint32_t index, | 6121 uint32_t index, |
| 6034 Object* holder) { | 6122 Object* holder) { |
| 6123 Heap* heap = GetHeap(); |
| 6035 ASSERT(!structure->IsProxy()); | 6124 ASSERT(!structure->IsProxy()); |
| 6036 | 6125 |
| 6037 // api style callbacks. | 6126 // api style callbacks. |
| 6038 if (structure->IsAccessorInfo()) { | 6127 if (structure->IsAccessorInfo()) { |
| 6039 AccessorInfo* data = AccessorInfo::cast(structure); | 6128 AccessorInfo* data = AccessorInfo::cast(structure); |
| 6040 Object* fun_obj = data->getter(); | 6129 Object* fun_obj = data->getter(); |
| 6041 v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj); | 6130 v8::AccessorGetter call_fun = v8::ToCData<v8::AccessorGetter>(fun_obj); |
| 6042 HandleScope scope; | 6131 HandleScope scope; |
| 6043 Handle<JSObject> self(JSObject::cast(receiver)); | 6132 Handle<JSObject> self(JSObject::cast(receiver)); |
| 6044 Handle<JSObject> holder_handle(JSObject::cast(holder)); | 6133 Handle<JSObject> holder_handle(JSObject::cast(holder)); |
| 6045 Handle<Object> number = Factory::NewNumberFromUint(index); | 6134 Handle<Object> number = Factory::NewNumberFromUint(index); |
| 6046 Handle<String> key(Factory::NumberToString(number)); | 6135 Handle<String> key(Factory::NumberToString(number)); |
| 6047 LOG(ApiNamedPropertyAccess("load", *self, *key)); | 6136 LOG(ApiNamedPropertyAccess("load", *self, *key)); |
| 6048 CustomArguments args(data->data(), *self, *holder_handle); | 6137 CustomArguments args(data->data(), *self, *holder_handle); |
| 6049 v8::AccessorInfo info(args.end()); | 6138 v8::AccessorInfo info(args.end()); |
| 6050 v8::Handle<v8::Value> result; | 6139 v8::Handle<v8::Value> result; |
| 6051 { | 6140 { |
| 6052 // Leaving JavaScript. | 6141 // Leaving JavaScript. |
| 6053 VMState state(EXTERNAL); | 6142 VMState state(EXTERNAL); |
| 6054 result = call_fun(v8::Utils::ToLocal(key), info); | 6143 result = call_fun(v8::Utils::ToLocal(key), info); |
| 6055 } | 6144 } |
| 6056 RETURN_IF_SCHEDULED_EXCEPTION(); | 6145 RETURN_IF_SCHEDULED_EXCEPTION(); |
| 6057 if (result.IsEmpty()) return HEAP->undefined_value(); | 6146 if (result.IsEmpty()) return heap->undefined_value(); |
| 6058 return *v8::Utils::OpenHandle(*result); | 6147 return *v8::Utils::OpenHandle(*result); |
| 6059 } | 6148 } |
| 6060 | 6149 |
| 6061 // __defineGetter__ callback | 6150 // __defineGetter__ callback |
| 6062 if (structure->IsFixedArray()) { | 6151 if (structure->IsFixedArray()) { |
| 6063 Object* getter = FixedArray::cast(structure)->get(kGetterIndex); | 6152 Object* getter = FixedArray::cast(structure)->get(kGetterIndex); |
| 6064 if (getter->IsJSFunction()) { | 6153 if (getter->IsJSFunction()) { |
| 6065 return Object::GetPropertyWithDefinedGetter(receiver, | 6154 return Object::GetPropertyWithDefinedGetter(receiver, |
| 6066 JSFunction::cast(getter)); | 6155 JSFunction::cast(getter)); |
| 6067 } | 6156 } |
| 6068 // Getter is not a function. | 6157 // Getter is not a function. |
| 6069 return HEAP->undefined_value(); | 6158 return heap->undefined_value(); |
| 6070 } | 6159 } |
| 6071 | 6160 |
| 6072 UNREACHABLE(); | 6161 UNREACHABLE(); |
| 6073 return NULL; | 6162 return NULL; |
| 6074 } | 6163 } |
| 6075 | 6164 |
| 6076 | 6165 |
| 6077 Object* JSObject::SetElementWithCallback(Object* structure, | 6166 Object* JSObject::SetElementWithCallback(Object* structure, |
| 6078 uint32_t index, | 6167 uint32_t index, |
| 6079 Object* value, | 6168 Object* value, |
| 6080 JSObject* holder) { | 6169 JSObject* holder) { |
| 6170 Heap* heap = GetHeap(); |
| 6081 HandleScope scope; | 6171 HandleScope scope; |
| 6082 | 6172 |
| 6083 // We should never get here to initialize a const with the hole | 6173 // We should never get here to initialize a const with the hole |
| 6084 // value since a const declaration would conflict with the setter. | 6174 // value since a const declaration would conflict with the setter. |
| 6085 ASSERT(!value->IsTheHole()); | 6175 ASSERT(!value->IsTheHole()); |
| 6086 Handle<Object> value_handle(value); | 6176 Handle<Object> value_handle(value); |
| 6087 | 6177 |
| 6088 // To accommodate both the old and the new api we switch on the | 6178 // To accommodate both the old and the new api we switch on the |
| 6089 // data structure used to store the callbacks. Eventually proxy | 6179 // data structure used to store the callbacks. Eventually proxy |
| 6090 // callbacks should be phased out. | 6180 // callbacks should be phased out. |
| (...skipping 22 matching lines...) Expand all Loading... |
| 6113 } | 6203 } |
| 6114 | 6204 |
| 6115 if (structure->IsFixedArray()) { | 6205 if (structure->IsFixedArray()) { |
| 6116 Object* setter = FixedArray::cast(structure)->get(kSetterIndex); | 6206 Object* setter = FixedArray::cast(structure)->get(kSetterIndex); |
| 6117 if (setter->IsJSFunction()) { | 6207 if (setter->IsJSFunction()) { |
| 6118 return SetPropertyWithDefinedSetter(JSFunction::cast(setter), value); | 6208 return SetPropertyWithDefinedSetter(JSFunction::cast(setter), value); |
| 6119 } else { | 6209 } else { |
| 6120 Handle<Object> holder_handle(holder); | 6210 Handle<Object> holder_handle(holder); |
| 6121 Handle<Object> key(Factory::NewNumberFromUint(index)); | 6211 Handle<Object> key(Factory::NewNumberFromUint(index)); |
| 6122 Handle<Object> args[2] = { key, holder_handle }; | 6212 Handle<Object> args[2] = { key, holder_handle }; |
| 6123 return Isolate::Current()->Throw( | 6213 return heap->isolate()->Throw( |
| 6124 *Factory::NewTypeError("no_setter_in_callback", | 6214 *Factory::NewTypeError("no_setter_in_callback", |
| 6125 HandleVector(args, 2))); | 6215 HandleVector(args, 2))); |
| 6126 } | 6216 } |
| 6127 } | 6217 } |
| 6128 | 6218 |
| 6129 UNREACHABLE(); | 6219 UNREACHABLE(); |
| 6130 return NULL; | 6220 return NULL; |
| 6131 } | 6221 } |
| 6132 | 6222 |
| 6133 | 6223 |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6175 } | 6265 } |
| 6176 | 6266 |
| 6177 // Otherwise default to slow case. | 6267 // Otherwise default to slow case. |
| 6178 Object* obj = NormalizeElements(); | 6268 Object* obj = NormalizeElements(); |
| 6179 if (obj->IsFailure()) return obj; | 6269 if (obj->IsFailure()) return obj; |
| 6180 ASSERT(HasDictionaryElements()); | 6270 ASSERT(HasDictionaryElements()); |
| 6181 return SetElement(index, value); | 6271 return SetElement(index, value); |
| 6182 } | 6272 } |
| 6183 | 6273 |
| 6184 Object* JSObject::SetElement(uint32_t index, Object* value) { | 6274 Object* JSObject::SetElement(uint32_t index, Object* value) { |
| 6275 Heap* heap = GetHeap(); |
| 6185 // Check access rights if needed. | 6276 // Check access rights if needed. |
| 6186 if (IsAccessCheckNeeded() && | 6277 if (IsAccessCheckNeeded() && |
| 6187 !Isolate::Current()->MayIndexedAccess(this, index, v8::ACCESS_SET)) { | 6278 !heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_SET)) { |
| 6188 Isolate::Current()->ReportFailedAccessCheck(this, v8::ACCESS_SET); | 6279 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_SET); |
| 6189 return value; | 6280 return value; |
| 6190 } | 6281 } |
| 6191 | 6282 |
| 6192 if (IsJSGlobalProxy()) { | 6283 if (IsJSGlobalProxy()) { |
| 6193 Object* proto = GetPrototype(); | 6284 Object* proto = GetPrototype(); |
| 6194 if (proto->IsNull()) return value; | 6285 if (proto->IsNull()) return value; |
| 6195 ASSERT(proto->IsJSGlobalObject()); | 6286 ASSERT(proto->IsJSGlobalObject()); |
| 6196 return JSObject::cast(proto)->SetElement(index, value); | 6287 return JSObject::cast(proto)->SetElement(index, value); |
| 6197 } | 6288 } |
| 6198 | 6289 |
| 6199 // Check for lookup interceptor | 6290 // Check for lookup interceptor |
| 6200 if (HasIndexedInterceptor()) { | 6291 if (HasIndexedInterceptor()) { |
| 6201 return SetElementWithInterceptor(index, value); | 6292 return SetElementWithInterceptor(index, value); |
| 6202 } | 6293 } |
| 6203 | 6294 |
| 6204 return SetElementWithoutInterceptor(index, value); | 6295 return SetElementWithoutInterceptor(index, value); |
| 6205 } | 6296 } |
| 6206 | 6297 |
| 6207 | 6298 |
| 6208 Object* JSObject::SetElementWithoutInterceptor(uint32_t index, Object* value) { | 6299 Object* JSObject::SetElementWithoutInterceptor(uint32_t index, Object* value) { |
| 6300 Heap* heap = GetHeap(); |
| 6209 switch (GetElementsKind()) { | 6301 switch (GetElementsKind()) { |
| 6210 case FAST_ELEMENTS: | 6302 case FAST_ELEMENTS: |
| 6211 // Fast case. | 6303 // Fast case. |
| 6212 return SetFastElement(index, value); | 6304 return SetFastElement(index, value); |
| 6213 case PIXEL_ELEMENTS: { | 6305 case PIXEL_ELEMENTS: { |
| 6214 PixelArray* pixels = PixelArray::cast(elements()); | 6306 PixelArray* pixels = PixelArray::cast(elements()); |
| 6215 return pixels->SetValue(index, value); | 6307 return pixels->SetValue(index, value); |
| 6216 } | 6308 } |
| 6217 case EXTERNAL_BYTE_ELEMENTS: { | 6309 case EXTERNAL_BYTE_ELEMENTS: { |
| 6218 ExternalByteArray* array = ExternalByteArray::cast(elements()); | 6310 ExternalByteArray* array = ExternalByteArray::cast(elements()); |
| (...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6263 } else { | 6355 } else { |
| 6264 // Index not already used. Look for an accessor in the prototype chain. | 6356 // Index not already used. Look for an accessor in the prototype chain. |
| 6265 if (!IsJSArray()) { | 6357 if (!IsJSArray()) { |
| 6266 if (SetElementWithCallbackSetterInPrototypes(index, value)) { | 6358 if (SetElementWithCallbackSetterInPrototypes(index, value)) { |
| 6267 return value; | 6359 return value; |
| 6268 } | 6360 } |
| 6269 } | 6361 } |
| 6270 // When we set the is_extensible flag to false we always force | 6362 // When we set the is_extensible flag to false we always force |
| 6271 // the element into dictionary mode (and force them to stay there). | 6363 // the element into dictionary mode (and force them to stay there). |
| 6272 if (!map()->is_extensible()) { | 6364 if (!map()->is_extensible()) { |
| 6273 Handle<Object> number(HEAP->NumberFromUint32(index)); | 6365 Handle<Object> number(heap->NumberFromUint32(index)); |
| 6274 Handle<String> index_string(Factory::NumberToString(number)); | 6366 Handle<String> index_string(Factory::NumberToString(number)); |
| 6275 Handle<Object> args[1] = { index_string }; | 6367 Handle<Object> args[1] = { index_string }; |
| 6276 return Isolate::Current()->Throw( | 6368 return heap->isolate()->Throw( |
| 6277 *Factory::NewTypeError("object_not_extensible", | 6369 *Factory::NewTypeError("object_not_extensible", |
| 6278 HandleVector(args, 1))); | 6370 HandleVector(args, 1))); |
| 6279 } | 6371 } |
| 6280 Object* result = dictionary->AtNumberPut(index, value); | 6372 Object* result = dictionary->AtNumberPut(index, value); |
| 6281 if (result->IsFailure()) return result; | 6373 if (result->IsFailure()) return result; |
| 6282 if (elms != FixedArray::cast(result)) { | 6374 if (elms != FixedArray::cast(result)) { |
| 6283 set_elements(FixedArray::cast(result)); | 6375 set_elements(FixedArray::cast(result)); |
| 6284 } | 6376 } |
| 6285 } | 6377 } |
| 6286 | 6378 |
| (...skipping 25 matching lines...) Expand all Loading... |
| 6312 | 6404 |
| 6313 return value; | 6405 return value; |
| 6314 } | 6406 } |
| 6315 default: | 6407 default: |
| 6316 UNREACHABLE(); | 6408 UNREACHABLE(); |
| 6317 break; | 6409 break; |
| 6318 } | 6410 } |
| 6319 // All possible cases have been handled above. Add a return to avoid the | 6411 // All possible cases have been handled above. Add a return to avoid the |
| 6320 // complaints from the compiler. | 6412 // complaints from the compiler. |
| 6321 UNREACHABLE(); | 6413 UNREACHABLE(); |
| 6322 return HEAP->null_value(); | 6414 return heap->null_value(); |
| 6323 } | 6415 } |
| 6324 | 6416 |
| 6325 | 6417 |
| 6326 Object* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index, Object* value) { | 6418 Object* JSArray::JSArrayUpdateLengthFromIndex(uint32_t index, Object* value) { |
| 6419 Heap* heap = GetHeap(); |
| 6327 uint32_t old_len = 0; | 6420 uint32_t old_len = 0; |
| 6328 CHECK(length()->ToArrayIndex(&old_len)); | 6421 CHECK(length()->ToArrayIndex(&old_len)); |
| 6329 // Check to see if we need to update the length. For now, we make | 6422 // Check to see if we need to update the length. For now, we make |
| 6330 // sure that the length stays within 32-bits (unsigned). | 6423 // sure that the length stays within 32-bits (unsigned). |
| 6331 if (index >= old_len && index != 0xffffffff) { | 6424 if (index >= old_len && index != 0xffffffff) { |
| 6332 Object* len = | 6425 Object* len = |
| 6333 HEAP->NumberFromDouble(static_cast<double>(index) + 1); | 6426 heap->NumberFromDouble(static_cast<double>(index) + 1); |
| 6334 if (len->IsFailure()) return len; | 6427 if (len->IsFailure()) return len; |
| 6335 set_length(len); | 6428 set_length(len); |
| 6336 } | 6429 } |
| 6337 return value; | 6430 return value; |
| 6338 } | 6431 } |
| 6339 | 6432 |
| 6340 | 6433 |
| 6341 Object* JSObject::GetElementPostInterceptor(JSObject* receiver, | 6434 Object* JSObject::GetElementPostInterceptor(JSObject* receiver, |
| 6342 uint32_t index) { | 6435 uint32_t index) { |
| 6436 Heap* heap = GetHeap(); |
| 6343 // Get element works for both JSObject and JSArray since | 6437 // Get element works for both JSObject and JSArray since |
| 6344 // JSArray::length cannot change. | 6438 // JSArray::length cannot change. |
| 6345 switch (GetElementsKind()) { | 6439 switch (GetElementsKind()) { |
| 6346 case FAST_ELEMENTS: { | 6440 case FAST_ELEMENTS: { |
| 6347 FixedArray* elms = FixedArray::cast(elements()); | 6441 FixedArray* elms = FixedArray::cast(elements()); |
| 6348 if (index < static_cast<uint32_t>(elms->length())) { | 6442 if (index < static_cast<uint32_t>(elms->length())) { |
| 6349 Object* value = elms->get(index); | 6443 Object* value = elms->get(index); |
| 6350 if (!value->IsTheHole()) return value; | 6444 if (!value->IsTheHole()) return value; |
| 6351 } | 6445 } |
| 6352 break; | 6446 break; |
| (...skipping 30 matching lines...) Expand all Loading... |
| 6383 } | 6477 } |
| 6384 break; | 6478 break; |
| 6385 } | 6479 } |
| 6386 default: | 6480 default: |
| 6387 UNREACHABLE(); | 6481 UNREACHABLE(); |
| 6388 break; | 6482 break; |
| 6389 } | 6483 } |
| 6390 | 6484 |
| 6391 // Continue searching via the prototype chain. | 6485 // Continue searching via the prototype chain. |
| 6392 Object* pt = GetPrototype(); | 6486 Object* pt = GetPrototype(); |
| 6393 if (pt->IsNull()) return HEAP->undefined_value(); | 6487 if (pt->IsNull()) return heap->undefined_value(); |
| 6394 return pt->GetElementWithReceiver(receiver, index); | 6488 return pt->GetElementWithReceiver(receiver, index); |
| 6395 } | 6489 } |
| 6396 | 6490 |
| 6397 | 6491 |
| 6398 Object* JSObject::GetElementWithInterceptor(JSObject* receiver, | 6492 Object* JSObject::GetElementWithInterceptor(JSObject* receiver, |
| 6399 uint32_t index) { | 6493 uint32_t index) { |
| 6400 // Make sure that the top context does not change when doing | 6494 // Make sure that the top context does not change when doing |
| 6401 // callbacks or interceptor calls. | 6495 // callbacks or interceptor calls. |
| 6402 AssertNoContextChange ncc; | 6496 AssertNoContextChange ncc; |
| 6403 HandleScope scope; | 6497 HandleScope scope; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 6422 } | 6516 } |
| 6423 | 6517 |
| 6424 Object* raw_result = | 6518 Object* raw_result = |
| 6425 holder_handle->GetElementPostInterceptor(*this_handle, index); | 6519 holder_handle->GetElementPostInterceptor(*this_handle, index); |
| 6426 RETURN_IF_SCHEDULED_EXCEPTION(); | 6520 RETURN_IF_SCHEDULED_EXCEPTION(); |
| 6427 return raw_result; | 6521 return raw_result; |
| 6428 } | 6522 } |
| 6429 | 6523 |
| 6430 | 6524 |
| 6431 Object* JSObject::GetElementWithReceiver(JSObject* receiver, uint32_t index) { | 6525 Object* JSObject::GetElementWithReceiver(JSObject* receiver, uint32_t index) { |
| 6526 Heap* heap = GetHeap(); |
| 6432 // Check access rights if needed. | 6527 // Check access rights if needed. |
| 6433 if (IsAccessCheckNeeded() && | 6528 if (IsAccessCheckNeeded() && |
| 6434 !Isolate::Current()->MayIndexedAccess(this, index, v8::ACCESS_GET)) { | 6529 !heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_GET)) { |
| 6435 Isolate::Current()->ReportFailedAccessCheck(this, v8::ACCESS_GET); | 6530 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_GET); |
| 6436 return HEAP->undefined_value(); | 6531 return heap->undefined_value(); |
| 6437 } | 6532 } |
| 6438 | 6533 |
| 6439 if (HasIndexedInterceptor()) { | 6534 if (HasIndexedInterceptor()) { |
| 6440 return GetElementWithInterceptor(receiver, index); | 6535 return GetElementWithInterceptor(receiver, index); |
| 6441 } | 6536 } |
| 6442 | 6537 |
| 6443 // Get element works for both JSObject and JSArray since | 6538 // Get element works for both JSObject and JSArray since |
| 6444 // JSArray::length cannot change. | 6539 // JSArray::length cannot change. |
| 6445 switch (GetElementsKind()) { | 6540 switch (GetElementsKind()) { |
| 6446 case FAST_ELEMENTS: { | 6541 case FAST_ELEMENTS: { |
| (...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6490 if (index < static_cast<uint32_t>(array->length())) { | 6585 if (index < static_cast<uint32_t>(array->length())) { |
| 6491 uint16_t value = array->get(index); | 6586 uint16_t value = array->get(index); |
| 6492 return Smi::FromInt(value); | 6587 return Smi::FromInt(value); |
| 6493 } | 6588 } |
| 6494 break; | 6589 break; |
| 6495 } | 6590 } |
| 6496 case EXTERNAL_INT_ELEMENTS: { | 6591 case EXTERNAL_INT_ELEMENTS: { |
| 6497 ExternalIntArray* array = ExternalIntArray::cast(elements()); | 6592 ExternalIntArray* array = ExternalIntArray::cast(elements()); |
| 6498 if (index < static_cast<uint32_t>(array->length())) { | 6593 if (index < static_cast<uint32_t>(array->length())) { |
| 6499 int32_t value = array->get(index); | 6594 int32_t value = array->get(index); |
| 6500 return HEAP->NumberFromInt32(value); | 6595 return heap->NumberFromInt32(value); |
| 6501 } | 6596 } |
| 6502 break; | 6597 break; |
| 6503 } | 6598 } |
| 6504 case EXTERNAL_UNSIGNED_INT_ELEMENTS: { | 6599 case EXTERNAL_UNSIGNED_INT_ELEMENTS: { |
| 6505 ExternalUnsignedIntArray* array = | 6600 ExternalUnsignedIntArray* array = |
| 6506 ExternalUnsignedIntArray::cast(elements()); | 6601 ExternalUnsignedIntArray::cast(elements()); |
| 6507 if (index < static_cast<uint32_t>(array->length())) { | 6602 if (index < static_cast<uint32_t>(array->length())) { |
| 6508 uint32_t value = array->get(index); | 6603 uint32_t value = array->get(index); |
| 6509 return HEAP->NumberFromUint32(value); | 6604 return heap->NumberFromUint32(value); |
| 6510 } | 6605 } |
| 6511 break; | 6606 break; |
| 6512 } | 6607 } |
| 6513 case EXTERNAL_FLOAT_ELEMENTS: { | 6608 case EXTERNAL_FLOAT_ELEMENTS: { |
| 6514 ExternalFloatArray* array = ExternalFloatArray::cast(elements()); | 6609 ExternalFloatArray* array = ExternalFloatArray::cast(elements()); |
| 6515 if (index < static_cast<uint32_t>(array->length())) { | 6610 if (index < static_cast<uint32_t>(array->length())) { |
| 6516 float value = array->get(index); | 6611 float value = array->get(index); |
| 6517 return HEAP->AllocateHeapNumber(value); | 6612 return heap->AllocateHeapNumber(value); |
| 6518 } | 6613 } |
| 6519 break; | 6614 break; |
| 6520 } | 6615 } |
| 6521 case DICTIONARY_ELEMENTS: { | 6616 case DICTIONARY_ELEMENTS: { |
| 6522 NumberDictionary* dictionary = element_dictionary(); | 6617 NumberDictionary* dictionary = element_dictionary(); |
| 6523 int entry = dictionary->FindEntry(index); | 6618 int entry = dictionary->FindEntry(index); |
| 6524 if (entry != NumberDictionary::kNotFound) { | 6619 if (entry != NumberDictionary::kNotFound) { |
| 6525 Object* element = dictionary->ValueAt(entry); | 6620 Object* element = dictionary->ValueAt(entry); |
| 6526 PropertyDetails details = dictionary->DetailsAt(entry); | 6621 PropertyDetails details = dictionary->DetailsAt(entry); |
| 6527 if (details.type() == CALLBACKS) { | 6622 if (details.type() == CALLBACKS) { |
| 6528 return GetElementWithCallback(receiver, | 6623 return GetElementWithCallback(receiver, |
| 6529 element, | 6624 element, |
| 6530 index, | 6625 index, |
| 6531 this); | 6626 this); |
| 6532 } | 6627 } |
| 6533 return element; | 6628 return element; |
| 6534 } | 6629 } |
| 6535 break; | 6630 break; |
| 6536 } | 6631 } |
| 6537 } | 6632 } |
| 6538 | 6633 |
| 6539 Object* pt = GetPrototype(); | 6634 Object* pt = GetPrototype(); |
| 6540 if (pt->IsNull()) return HEAP->undefined_value(); | 6635 if (pt->IsNull()) return heap->undefined_value(); |
| 6541 return pt->GetElementWithReceiver(receiver, index); | 6636 return pt->GetElementWithReceiver(receiver, index); |
| 6542 } | 6637 } |
| 6543 | 6638 |
| 6544 | 6639 |
| 6545 bool JSObject::HasDenseElements() { | 6640 bool JSObject::HasDenseElements() { |
| 6546 int capacity = 0; | 6641 int capacity = 0; |
| 6547 int number_of_elements = 0; | 6642 int number_of_elements = 0; |
| 6548 | 6643 |
| 6549 switch (GetElementsKind()) { | 6644 switch (GetElementsKind()) { |
| 6550 case FAST_ELEMENTS: { | 6645 case FAST_ELEMENTS: { |
| (...skipping 124 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6675 ASSERT(constructor->shared()->IsApiFunction()); | 6770 ASSERT(constructor->shared()->IsApiFunction()); |
| 6676 Object* result = | 6771 Object* result = |
| 6677 constructor->shared()->get_api_func_data()->indexed_property_handler(); | 6772 constructor->shared()->get_api_func_data()->indexed_property_handler(); |
| 6678 return InterceptorInfo::cast(result); | 6773 return InterceptorInfo::cast(result); |
| 6679 } | 6774 } |
| 6680 | 6775 |
| 6681 | 6776 |
| 6682 Object* JSObject::GetPropertyPostInterceptor(JSObject* receiver, | 6777 Object* JSObject::GetPropertyPostInterceptor(JSObject* receiver, |
| 6683 String* name, | 6778 String* name, |
| 6684 PropertyAttributes* attributes) { | 6779 PropertyAttributes* attributes) { |
| 6780 Heap* heap = GetHeap(); |
| 6685 // Check local property in holder, ignore interceptor. | 6781 // Check local property in holder, ignore interceptor. |
| 6686 LookupResult result; | 6782 LookupResult result; |
| 6687 LocalLookupRealNamedProperty(name, &result); | 6783 LocalLookupRealNamedProperty(name, &result); |
| 6688 if (result.IsProperty()) { | 6784 if (result.IsProperty()) { |
| 6689 return GetProperty(receiver, &result, name, attributes); | 6785 return GetProperty(receiver, &result, name, attributes); |
| 6690 } | 6786 } |
| 6691 // Continue searching via the prototype chain. | 6787 // Continue searching via the prototype chain. |
| 6692 Object* pt = GetPrototype(); | 6788 Object* pt = GetPrototype(); |
| 6693 *attributes = ABSENT; | 6789 *attributes = ABSENT; |
| 6694 if (pt->IsNull()) return HEAP->undefined_value(); | 6790 if (pt->IsNull()) return heap->undefined_value(); |
| 6695 return pt->GetPropertyWithReceiver(receiver, name, attributes); | 6791 return pt->GetPropertyWithReceiver(receiver, name, attributes); |
| 6696 } | 6792 } |
| 6697 | 6793 |
| 6698 | 6794 |
| 6699 Object* JSObject::GetLocalPropertyPostInterceptor( | 6795 Object* JSObject::GetLocalPropertyPostInterceptor( |
| 6700 JSObject* receiver, | 6796 JSObject* receiver, |
| 6701 String* name, | 6797 String* name, |
| 6702 PropertyAttributes* attributes) { | 6798 PropertyAttributes* attributes) { |
| 6799 Heap* heap = GetHeap(); |
| 6703 // Check local property in holder, ignore interceptor. | 6800 // Check local property in holder, ignore interceptor. |
| 6704 LookupResult result; | 6801 LookupResult result; |
| 6705 LocalLookupRealNamedProperty(name, &result); | 6802 LocalLookupRealNamedProperty(name, &result); |
| 6706 if (result.IsProperty()) { | 6803 if (result.IsProperty()) { |
| 6707 return GetProperty(receiver, &result, name, attributes); | 6804 return GetProperty(receiver, &result, name, attributes); |
| 6708 } | 6805 } |
| 6709 return HEAP->undefined_value(); | 6806 return heap->undefined_value(); |
| 6710 } | 6807 } |
| 6711 | 6808 |
| 6712 | 6809 |
| 6713 Object* JSObject::GetPropertyWithInterceptor( | 6810 Object* JSObject::GetPropertyWithInterceptor( |
| 6714 JSObject* receiver, | 6811 JSObject* receiver, |
| 6715 String* name, | 6812 String* name, |
| 6716 PropertyAttributes* attributes) { | 6813 PropertyAttributes* attributes) { |
| 6717 InterceptorInfo* interceptor = GetNamedInterceptor(); | 6814 InterceptorInfo* interceptor = GetNamedInterceptor(); |
| 6718 HandleScope scope; | 6815 HandleScope scope; |
| 6719 Handle<JSObject> receiver_handle(receiver); | 6816 Handle<JSObject> receiver_handle(receiver); |
| (...skipping 22 matching lines...) Expand all Loading... |
| 6742 Object* result = holder_handle->GetPropertyPostInterceptor( | 6839 Object* result = holder_handle->GetPropertyPostInterceptor( |
| 6743 *receiver_handle, | 6840 *receiver_handle, |
| 6744 *name_handle, | 6841 *name_handle, |
| 6745 attributes); | 6842 attributes); |
| 6746 RETURN_IF_SCHEDULED_EXCEPTION(); | 6843 RETURN_IF_SCHEDULED_EXCEPTION(); |
| 6747 return result; | 6844 return result; |
| 6748 } | 6845 } |
| 6749 | 6846 |
| 6750 | 6847 |
| 6751 bool JSObject::HasRealNamedProperty(String* key) { | 6848 bool JSObject::HasRealNamedProperty(String* key) { |
| 6849 Heap* heap = GetHeap(); |
| 6752 // Check access rights if needed. | 6850 // Check access rights if needed. |
| 6753 if (IsAccessCheckNeeded() && | 6851 if (IsAccessCheckNeeded() && |
| 6754 !Isolate::Current()->MayNamedAccess(this, key, v8::ACCESS_HAS)) { | 6852 !heap->isolate()->MayNamedAccess(this, key, v8::ACCESS_HAS)) { |
| 6755 Isolate::Current()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 6853 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 6756 return false; | 6854 return false; |
| 6757 } | 6855 } |
| 6758 | 6856 |
| 6759 LookupResult result; | 6857 LookupResult result; |
| 6760 LocalLookupRealNamedProperty(key, &result); | 6858 LocalLookupRealNamedProperty(key, &result); |
| 6761 return result.IsProperty() && (result.type() != INTERCEPTOR); | 6859 return result.IsProperty() && (result.type() != INTERCEPTOR); |
| 6762 } | 6860 } |
| 6763 | 6861 |
| 6764 | 6862 |
| 6765 bool JSObject::HasRealElementProperty(uint32_t index) { | 6863 bool JSObject::HasRealElementProperty(uint32_t index) { |
| 6864 Heap* heap = GetHeap(); |
| 6766 // Check access rights if needed. | 6865 // Check access rights if needed. |
| 6767 if (IsAccessCheckNeeded() && | 6866 if (IsAccessCheckNeeded() && |
| 6768 !Isolate::Current()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { | 6867 !heap->isolate()->MayIndexedAccess(this, index, v8::ACCESS_HAS)) { |
| 6769 Isolate::Current()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 6868 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 6770 return false; | 6869 return false; |
| 6771 } | 6870 } |
| 6772 | 6871 |
| 6773 // Handle [] on String objects. | 6872 // Handle [] on String objects. |
| 6774 if (this->IsStringObjectWithCharacterAt(index)) return true; | 6873 if (this->IsStringObjectWithCharacterAt(index)) return true; |
| 6775 | 6874 |
| 6776 switch (GetElementsKind()) { | 6875 switch (GetElementsKind()) { |
| 6777 case FAST_ELEMENTS: { | 6876 case FAST_ELEMENTS: { |
| 6778 uint32_t length = IsJSArray() ? | 6877 uint32_t length = IsJSArray() ? |
| 6779 static_cast<uint32_t>( | 6878 static_cast<uint32_t>( |
| (...skipping 19 matching lines...) Expand all Loading... |
| 6799 case DICTIONARY_ELEMENTS: { | 6898 case DICTIONARY_ELEMENTS: { |
| 6800 return element_dictionary()->FindEntry(index) | 6899 return element_dictionary()->FindEntry(index) |
| 6801 != NumberDictionary::kNotFound; | 6900 != NumberDictionary::kNotFound; |
| 6802 } | 6901 } |
| 6803 default: | 6902 default: |
| 6804 UNREACHABLE(); | 6903 UNREACHABLE(); |
| 6805 break; | 6904 break; |
| 6806 } | 6905 } |
| 6807 // All possibilities have been handled above already. | 6906 // All possibilities have been handled above already. |
| 6808 UNREACHABLE(); | 6907 UNREACHABLE(); |
| 6809 return HEAP->null_value(); | 6908 return heap->null_value(); |
| 6810 } | 6909 } |
| 6811 | 6910 |
| 6812 | 6911 |
| 6813 bool JSObject::HasRealNamedCallbackProperty(String* key) { | 6912 bool JSObject::HasRealNamedCallbackProperty(String* key) { |
| 6913 Heap* heap = GetHeap(); |
| 6814 // Check access rights if needed. | 6914 // Check access rights if needed. |
| 6815 if (IsAccessCheckNeeded() && | 6915 if (IsAccessCheckNeeded() && |
| 6816 !Isolate::Current()->MayNamedAccess(this, key, v8::ACCESS_HAS)) { | 6916 !heap->isolate()->MayNamedAccess(this, key, v8::ACCESS_HAS)) { |
| 6817 Isolate::Current()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); | 6917 heap->isolate()->ReportFailedAccessCheck(this, v8::ACCESS_HAS); |
| 6818 return false; | 6918 return false; |
| 6819 } | 6919 } |
| 6820 | 6920 |
| 6821 LookupResult result; | 6921 LookupResult result; |
| 6822 LocalLookupRealNamedProperty(key, &result); | 6922 LocalLookupRealNamedProperty(key, &result); |
| 6823 return result.IsProperty() && (result.type() == CALLBACKS); | 6923 return result.IsProperty() && (result.type() == CALLBACKS); |
| 6824 } | 6924 } |
| 6825 | 6925 |
| 6826 | 6926 |
| 6827 int JSObject::NumberOfLocalProperties(PropertyAttributes filter) { | 6927 int JSObject::NumberOfLocalProperties(PropertyAttributes filter) { |
| (...skipping 260 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7088 } | 7188 } |
| 7089 | 7189 |
| 7090 | 7190 |
| 7091 uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) { | 7191 uint32_t NumberDictionaryShape::HashForObject(uint32_t key, Object* other) { |
| 7092 ASSERT(other->IsNumber()); | 7192 ASSERT(other->IsNumber()); |
| 7093 return ComputeIntegerHash(static_cast<uint32_t>(other->Number())); | 7193 return ComputeIntegerHash(static_cast<uint32_t>(other->Number())); |
| 7094 } | 7194 } |
| 7095 | 7195 |
| 7096 | 7196 |
| 7097 Object* NumberDictionaryShape::AsObject(uint32_t key) { | 7197 Object* NumberDictionaryShape::AsObject(uint32_t key) { |
| 7098 return HEAP->NumberFromUint32(key); | 7198 return Isolate::Current()->heap()->NumberFromUint32(key); |
| 7099 } | 7199 } |
| 7100 | 7200 |
| 7101 | 7201 |
| 7102 bool StringDictionaryShape::IsMatch(String* key, Object* other) { | 7202 bool StringDictionaryShape::IsMatch(String* key, Object* other) { |
| 7103 // We know that all entries in a hash table had their hash keys created. | 7203 // We know that all entries in a hash table had their hash keys created. |
| 7104 // Use that knowledge to have fast failure. | 7204 // Use that knowledge to have fast failure. |
| 7105 if (key->Hash() != String::cast(other)->Hash()) return false; | 7205 if (key->Hash() != String::cast(other)->Hash()) return false; |
| 7106 return key->Equals(String::cast(other)); | 7206 return key->Equals(String::cast(other)); |
| 7107 } | 7207 } |
| 7108 | 7208 |
| (...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7185 } | 7285 } |
| 7186 | 7286 |
| 7187 uint32_t HashForObject(Object* obj) { | 7287 uint32_t HashForObject(Object* obj) { |
| 7188 FixedArray* pair = FixedArray::cast(obj); | 7288 FixedArray* pair = FixedArray::cast(obj); |
| 7189 SharedFunctionInfo* shared = SharedFunctionInfo::cast(pair->get(0)); | 7289 SharedFunctionInfo* shared = SharedFunctionInfo::cast(pair->get(0)); |
| 7190 String* source = String::cast(pair->get(1)); | 7290 String* source = String::cast(pair->get(1)); |
| 7191 return StringSharedHashHelper(source, shared); | 7291 return StringSharedHashHelper(source, shared); |
| 7192 } | 7292 } |
| 7193 | 7293 |
| 7194 Object* AsObject() { | 7294 Object* AsObject() { |
| 7195 Object* obj = HEAP->AllocateFixedArray(2); | 7295 Object* obj = shared_->GetHeap()->AllocateFixedArray(2); |
| 7196 if (obj->IsFailure()) return obj; | 7296 if (obj->IsFailure()) return obj; |
| 7197 FixedArray* pair = FixedArray::cast(obj); | 7297 FixedArray* pair = FixedArray::cast(obj); |
| 7198 pair->set(0, shared_); | 7298 pair->set(0, shared_); |
| 7199 pair->set(1, source_); | 7299 pair->set(1, source_); |
| 7200 return pair; | 7300 return pair; |
| 7201 } | 7301 } |
| 7202 | 7302 |
| 7203 private: | 7303 private: |
| 7204 String* source_; | 7304 String* source_; |
| 7205 SharedFunctionInfo* shared_; | 7305 SharedFunctionInfo* shared_; |
| (...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7266 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. | 7366 ASSERT(result != 0); // Ensure that the hash value of 0 is never computed. |
| 7267 return result; | 7367 return result; |
| 7268 } | 7368 } |
| 7269 | 7369 |
| 7270 uint32_t HashForObject(Object* other) { | 7370 uint32_t HashForObject(Object* other) { |
| 7271 return String::cast(other)->Hash(); | 7371 return String::cast(other)->Hash(); |
| 7272 } | 7372 } |
| 7273 | 7373 |
| 7274 Object* AsObject() { | 7374 Object* AsObject() { |
| 7275 if (hash_field_ == 0) Hash(); | 7375 if (hash_field_ == 0) Hash(); |
| 7276 return HEAP->AllocateSymbol(string_, chars_, hash_field_); | 7376 return Isolate::Current()->heap()->AllocateSymbol( |
| 7377 string_, chars_, hash_field_); |
| 7277 } | 7378 } |
| 7278 | 7379 |
| 7279 Vector<const char> string_; | 7380 Vector<const char> string_; |
| 7280 uint32_t hash_field_; | 7381 uint32_t hash_field_; |
| 7281 int chars_; // Caches the number of characters when computing the hash code. | 7382 int chars_; // Caches the number of characters when computing the hash code. |
| 7282 }; | 7383 }; |
| 7283 | 7384 |
| 7284 | 7385 |
| 7285 // SymbolKey carries a string/symbol object as key. | 7386 // SymbolKey carries a string/symbol object as key. |
| 7286 class SymbolKey : public HashTableKey { | 7387 class SymbolKey : public HashTableKey { |
| 7287 public: | 7388 public: |
| 7288 explicit SymbolKey(String* string) : string_(string) { } | 7389 explicit SymbolKey(String* string) |
| 7390 : string_(string) { } |
| 7289 | 7391 |
| 7290 bool IsMatch(Object* string) { | 7392 bool IsMatch(Object* string) { |
| 7291 return String::cast(string)->Equals(string_); | 7393 return String::cast(string)->Equals(string_); |
| 7292 } | 7394 } |
| 7293 | 7395 |
| 7294 uint32_t Hash() { return string_->Hash(); } | 7396 uint32_t Hash() { return string_->Hash(); } |
| 7295 | 7397 |
| 7296 uint32_t HashForObject(Object* other) { | 7398 uint32_t HashForObject(Object* other) { |
| 7297 return String::cast(other)->Hash(); | 7399 return String::cast(other)->Hash(); |
| 7298 } | 7400 } |
| 7299 | 7401 |
| 7300 Object* AsObject() { | 7402 Object* AsObject() { |
| 7301 // Attempt to flatten the string, so that symbols will most often | 7403 // Attempt to flatten the string, so that symbols will most often |
| 7302 // be flat strings. | 7404 // be flat strings. |
| 7303 string_ = string_->TryFlattenGetString(); | 7405 string_ = string_->TryFlattenGetString(); |
| 7406 Heap* heap = string_->GetHeap(); |
| 7304 // Transform string to symbol if possible. | 7407 // Transform string to symbol if possible. |
| 7305 Map* map = HEAP->SymbolMapForString(string_); | 7408 Map* map = heap->SymbolMapForString(string_); |
| 7306 if (map != NULL) { | 7409 if (map != NULL) { |
| 7307 string_->set_map(map); | 7410 string_->set_map(map); |
| 7308 ASSERT(string_->IsSymbol()); | 7411 ASSERT(string_->IsSymbol()); |
| 7309 return string_; | 7412 return string_; |
| 7310 } | 7413 } |
| 7311 // Otherwise allocate a new symbol. | 7414 // Otherwise allocate a new symbol. |
| 7312 StringInputBuffer buffer(string_); | 7415 StringInputBuffer buffer(string_); |
| 7313 return HEAP->AllocateInternalSymbol(&buffer, | 7416 return heap->AllocateInternalSymbol(&buffer, |
| 7314 string_->length(), | 7417 string_->length(), |
| 7315 string_->hash_field()); | 7418 string_->hash_field()); |
| 7316 } | 7419 } |
| 7317 | 7420 |
| 7318 static uint32_t StringHash(Object* obj) { | 7421 static uint32_t StringHash(Object* obj) { |
| 7319 return String::cast(obj)->Hash(); | 7422 return String::cast(obj)->Hash(); |
| 7320 } | 7423 } |
| 7321 | 7424 |
| 7322 String* string_; | 7425 String* string_; |
| 7323 }; | 7426 }; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 7341 Object* HashTable<Shape, Key>::Allocate(int at_least_space_for, | 7444 Object* HashTable<Shape, Key>::Allocate(int at_least_space_for, |
| 7342 PretenureFlag pretenure) { | 7445 PretenureFlag pretenure) { |
| 7343 const int kMinCapacity = 32; | 7446 const int kMinCapacity = 32; |
| 7344 int capacity = RoundUpToPowerOf2(at_least_space_for * 2); | 7447 int capacity = RoundUpToPowerOf2(at_least_space_for * 2); |
| 7345 if (capacity < kMinCapacity) { | 7448 if (capacity < kMinCapacity) { |
| 7346 capacity = kMinCapacity; // Guarantee min capacity. | 7449 capacity = kMinCapacity; // Guarantee min capacity. |
| 7347 } else if (capacity > HashTable::kMaxCapacity) { | 7450 } else if (capacity > HashTable::kMaxCapacity) { |
| 7348 return Failure::OutOfMemoryException(); | 7451 return Failure::OutOfMemoryException(); |
| 7349 } | 7452 } |
| 7350 | 7453 |
| 7351 Object* obj = HEAP->AllocateHashTable(EntryToIndex(capacity), pretenure); | 7454 Object* obj = Isolate::Current()->heap()->AllocateHashTable( |
| 7455 EntryToIndex(capacity), pretenure); |
| 7352 if (!obj->IsFailure()) { | 7456 if (!obj->IsFailure()) { |
| 7353 HashTable::cast(obj)->SetNumberOfElements(0); | 7457 HashTable::cast(obj)->SetNumberOfElements(0); |
| 7354 HashTable::cast(obj)->SetNumberOfDeletedElements(0); | 7458 HashTable::cast(obj)->SetNumberOfDeletedElements(0); |
| 7355 HashTable::cast(obj)->SetCapacity(capacity); | 7459 HashTable::cast(obj)->SetCapacity(capacity); |
| 7356 } | 7460 } |
| 7357 return obj; | 7461 return obj; |
| 7358 } | 7462 } |
| 7359 | 7463 |
| 7360 | 7464 |
| 7361 // Find entry for key otherwise return kNotFound. | 7465 // Find entry for key otherwise return kNotFound. |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7410 } | 7514 } |
| 7411 ASSERT(element->IsNull() || !String::cast(element)->Equals(key)); | 7515 ASSERT(element->IsNull() || !String::cast(element)->Equals(key)); |
| 7412 entry = NextProbe(entry, count++, capacity); | 7516 entry = NextProbe(entry, count++, capacity); |
| 7413 } | 7517 } |
| 7414 return kNotFound; | 7518 return kNotFound; |
| 7415 } | 7519 } |
| 7416 | 7520 |
| 7417 | 7521 |
| 7418 template<typename Shape, typename Key> | 7522 template<typename Shape, typename Key> |
| 7419 Object* HashTable<Shape, Key>::EnsureCapacity(int n, Key key) { | 7523 Object* HashTable<Shape, Key>::EnsureCapacity(int n, Key key) { |
| 7524 Heap* heap = GetHeap(); |
| 7420 int capacity = Capacity(); | 7525 int capacity = Capacity(); |
| 7421 int nof = NumberOfElements() + n; | 7526 int nof = NumberOfElements() + n; |
| 7422 int nod = NumberOfDeletedElements(); | 7527 int nod = NumberOfDeletedElements(); |
| 7423 // Return if: | 7528 // Return if: |
| 7424 // 50% is still free after adding n elements and | 7529 // 50% is still free after adding n elements and |
| 7425 // at most 50% of the free elements are deleted elements. | 7530 // at most 50% of the free elements are deleted elements. |
| 7426 if (nod <= (capacity - nof) >> 1) { | 7531 if (nod <= (capacity - nof) >> 1) { |
| 7427 int needed_free = nof >> 1; | 7532 int needed_free = nof >> 1; |
| 7428 if (nof + needed_free <= capacity) return this; | 7533 if (nof + needed_free <= capacity) return this; |
| 7429 } | 7534 } |
| 7430 | 7535 |
| 7431 const int kMinCapacityForPretenure = 256; | 7536 const int kMinCapacityForPretenure = 256; |
| 7432 bool pretenure = | 7537 bool pretenure = |
| 7433 (capacity > kMinCapacityForPretenure) && !HEAP->InNewSpace(this); | 7538 (capacity > kMinCapacityForPretenure) && !heap->InNewSpace(this); |
| 7434 Object* obj = Allocate(nof * 2, pretenure ? TENURED : NOT_TENURED); | 7539 Object* obj = Allocate(nof * 2, pretenure ? TENURED : NOT_TENURED); |
| 7435 if (obj->IsFailure()) return obj; | 7540 if (obj->IsFailure()) return obj; |
| 7436 | 7541 |
| 7437 AssertNoAllocation no_gc; | 7542 AssertNoAllocation no_gc; |
| 7438 HashTable* table = HashTable::cast(obj); | 7543 HashTable* table = HashTable::cast(obj); |
| 7439 WriteBarrierMode mode = table->GetWriteBarrierMode(no_gc); | 7544 WriteBarrierMode mode = table->GetWriteBarrierMode(no_gc); |
| 7440 | 7545 |
| 7441 // Copy prefix to new array. | 7546 // Copy prefix to new array. |
| 7442 for (int i = kPrefixStartIndex; | 7547 for (int i = kPrefixStartIndex; |
| 7443 i < kPrefixStartIndex + Shape::kPrefixSize; | 7548 i < kPrefixStartIndex + Shape::kPrefixSize; |
| (...skipping 108 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7552 template | 7657 template |
| 7553 int Dictionary<StringDictionaryShape, String*>::NumberOfEnumElements(); | 7658 int Dictionary<StringDictionaryShape, String*>::NumberOfEnumElements(); |
| 7554 | 7659 |
| 7555 template | 7660 template |
| 7556 int HashTable<NumberDictionaryShape, uint32_t>::FindEntry(uint32_t); | 7661 int HashTable<NumberDictionaryShape, uint32_t>::FindEntry(uint32_t); |
| 7557 | 7662 |
| 7558 | 7663 |
| 7559 // Collates undefined and unexisting elements below limit from position | 7664 // Collates undefined and unexisting elements below limit from position |
| 7560 // zero of the elements. The object stays in Dictionary mode. | 7665 // zero of the elements. The object stays in Dictionary mode. |
| 7561 Object* JSObject::PrepareSlowElementsForSort(uint32_t limit) { | 7666 Object* JSObject::PrepareSlowElementsForSort(uint32_t limit) { |
| 7667 Heap* heap = GetHeap(); |
| 7562 ASSERT(HasDictionaryElements()); | 7668 ASSERT(HasDictionaryElements()); |
| 7563 // Must stay in dictionary mode, either because of requires_slow_elements, | 7669 // Must stay in dictionary mode, either because of requires_slow_elements, |
| 7564 // or because we are not going to sort (and therefore compact) all of the | 7670 // or because we are not going to sort (and therefore compact) all of the |
| 7565 // elements. | 7671 // elements. |
| 7566 NumberDictionary* dict = element_dictionary(); | 7672 NumberDictionary* dict = element_dictionary(); |
| 7567 HeapNumber* result_double = NULL; | 7673 HeapNumber* result_double = NULL; |
| 7568 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { | 7674 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { |
| 7569 // Allocate space for result before we start mutating the object. | 7675 // Allocate space for result before we start mutating the object. |
| 7570 Object* new_double = HEAP->AllocateHeapNumber(0.0); | 7676 Object* new_double = heap->AllocateHeapNumber(0.0); |
| 7571 if (new_double->IsFailure()) return new_double; | 7677 if (new_double->IsFailure()) return new_double; |
| 7572 result_double = HeapNumber::cast(new_double); | 7678 result_double = HeapNumber::cast(new_double); |
| 7573 } | 7679 } |
| 7574 | 7680 |
| 7575 Object* obj = NumberDictionary::Allocate(dict->NumberOfElements()); | 7681 Object* obj = NumberDictionary::Allocate(dict->NumberOfElements()); |
| 7576 if (obj->IsFailure()) return obj; | 7682 if (obj->IsFailure()) return obj; |
| 7577 NumberDictionary* new_dict = NumberDictionary::cast(obj); | 7683 NumberDictionary* new_dict = NumberDictionary::cast(obj); |
| 7578 | 7684 |
| 7579 AssertNoAllocation no_alloc; | 7685 AssertNoAllocation no_alloc; |
| 7580 | 7686 |
| (...skipping 23 matching lines...) Expand all Loading... |
| 7604 } | 7710 } |
| 7605 } else { | 7711 } else { |
| 7606 new_dict->AddNumberEntry(key, value, details); | 7712 new_dict->AddNumberEntry(key, value, details); |
| 7607 } | 7713 } |
| 7608 } | 7714 } |
| 7609 } | 7715 } |
| 7610 | 7716 |
| 7611 uint32_t result = pos; | 7717 uint32_t result = pos; |
| 7612 PropertyDetails no_details = PropertyDetails(NONE, NORMAL); | 7718 PropertyDetails no_details = PropertyDetails(NONE, NORMAL); |
| 7613 while (undefs > 0) { | 7719 while (undefs > 0) { |
| 7614 new_dict->AddNumberEntry(pos, HEAP->undefined_value(), no_details); | 7720 new_dict->AddNumberEntry(pos, heap->undefined_value(), no_details); |
| 7615 pos++; | 7721 pos++; |
| 7616 undefs--; | 7722 undefs--; |
| 7617 } | 7723 } |
| 7618 | 7724 |
| 7619 set_elements(new_dict); | 7725 set_elements(new_dict); |
| 7620 | 7726 |
| 7621 if (result <= static_cast<uint32_t>(Smi::kMaxValue)) { | 7727 if (result <= static_cast<uint32_t>(Smi::kMaxValue)) { |
| 7622 return Smi::FromInt(static_cast<int>(result)); | 7728 return Smi::FromInt(static_cast<int>(result)); |
| 7623 } | 7729 } |
| 7624 | 7730 |
| 7625 ASSERT_NE(NULL, result_double); | 7731 ASSERT_NE(NULL, result_double); |
| 7626 result_double->set_value(static_cast<double>(result)); | 7732 result_double->set_value(static_cast<double>(result)); |
| 7627 return result_double; | 7733 return result_double; |
| 7628 } | 7734 } |
| 7629 | 7735 |
| 7630 | 7736 |
| 7631 // Collects all defined (non-hole) and non-undefined (array) elements at | 7737 // Collects all defined (non-hole) and non-undefined (array) elements at |
| 7632 // the start of the elements array. | 7738 // the start of the elements array. |
| 7633 // If the object is in dictionary mode, it is converted to fast elements | 7739 // If the object is in dictionary mode, it is converted to fast elements |
| 7634 // mode. | 7740 // mode. |
| 7635 Object* JSObject::PrepareElementsForSort(uint32_t limit) { | 7741 Object* JSObject::PrepareElementsForSort(uint32_t limit) { |
| 7742 Heap* heap = GetHeap(); |
| 7636 ASSERT(!HasPixelElements() && !HasExternalArrayElements()); | 7743 ASSERT(!HasPixelElements() && !HasExternalArrayElements()); |
| 7637 | 7744 |
| 7638 if (HasDictionaryElements()) { | 7745 if (HasDictionaryElements()) { |
| 7639 // Convert to fast elements containing only the existing properties. | 7746 // Convert to fast elements containing only the existing properties. |
| 7640 // Ordering is irrelevant, since we are going to sort anyway. | 7747 // Ordering is irrelevant, since we are going to sort anyway. |
| 7641 NumberDictionary* dict = element_dictionary(); | 7748 NumberDictionary* dict = element_dictionary(); |
| 7642 if (IsJSArray() || dict->requires_slow_elements() || | 7749 if (IsJSArray() || dict->requires_slow_elements() || |
| 7643 dict->max_number_key() >= limit) { | 7750 dict->max_number_key() >= limit) { |
| 7644 return PrepareSlowElementsForSort(limit); | 7751 return PrepareSlowElementsForSort(limit); |
| 7645 } | 7752 } |
| 7646 // Convert to fast elements. | 7753 // Convert to fast elements. |
| 7647 | 7754 |
| 7648 Object* obj = map()->GetFastElementsMap(); | 7755 Object* obj = map()->GetFastElementsMap(); |
| 7649 if (obj->IsFailure()) return obj; | 7756 if (obj->IsFailure()) return obj; |
| 7650 Map* new_map = Map::cast(obj); | 7757 Map* new_map = Map::cast(obj); |
| 7651 | 7758 |
| 7652 PretenureFlag tenure = HEAP->InNewSpace(this) ? NOT_TENURED: TENURED; | 7759 PretenureFlag tenure = heap->InNewSpace(this) ? NOT_TENURED: TENURED; |
| 7653 Object* new_array = | 7760 Object* new_array = |
| 7654 HEAP->AllocateFixedArray(dict->NumberOfElements(), tenure); | 7761 heap->AllocateFixedArray(dict->NumberOfElements(), tenure); |
| 7655 if (new_array->IsFailure()) return new_array; | 7762 if (new_array->IsFailure()) return new_array; |
| 7656 FixedArray* fast_elements = FixedArray::cast(new_array); | 7763 FixedArray* fast_elements = FixedArray::cast(new_array); |
| 7657 dict->CopyValuesTo(fast_elements); | 7764 dict->CopyValuesTo(fast_elements); |
| 7658 | 7765 |
| 7659 set_map(new_map); | 7766 set_map(new_map); |
| 7660 set_elements(fast_elements); | 7767 set_elements(fast_elements); |
| 7661 } | 7768 } |
| 7662 ASSERT(HasFastElements()); | 7769 ASSERT(HasFastElements()); |
| 7663 | 7770 |
| 7664 // Collect holes at the end, undefined before that and the rest at the | 7771 // Collect holes at the end, undefined before that and the rest at the |
| 7665 // start, and return the number of non-hole, non-undefined values. | 7772 // start, and return the number of non-hole, non-undefined values. |
| 7666 | 7773 |
| 7667 FixedArray* elements = FixedArray::cast(this->elements()); | 7774 FixedArray* elements = FixedArray::cast(this->elements()); |
| 7668 uint32_t elements_length = static_cast<uint32_t>(elements->length()); | 7775 uint32_t elements_length = static_cast<uint32_t>(elements->length()); |
| 7669 if (limit > elements_length) { | 7776 if (limit > elements_length) { |
| 7670 limit = elements_length ; | 7777 limit = elements_length ; |
| 7671 } | 7778 } |
| 7672 if (limit == 0) { | 7779 if (limit == 0) { |
| 7673 return Smi::FromInt(0); | 7780 return Smi::FromInt(0); |
| 7674 } | 7781 } |
| 7675 | 7782 |
| 7676 HeapNumber* result_double = NULL; | 7783 HeapNumber* result_double = NULL; |
| 7677 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { | 7784 if (limit > static_cast<uint32_t>(Smi::kMaxValue)) { |
| 7678 // Pessimistically allocate space for return value before | 7785 // Pessimistically allocate space for return value before |
| 7679 // we start mutating the array. | 7786 // we start mutating the array. |
| 7680 Object* new_double = HEAP->AllocateHeapNumber(0.0); | 7787 Object* new_double = heap->AllocateHeapNumber(0.0); |
| 7681 if (new_double->IsFailure()) return new_double; | 7788 if (new_double->IsFailure()) return new_double; |
| 7682 result_double = HeapNumber::cast(new_double); | 7789 result_double = HeapNumber::cast(new_double); |
| 7683 } | 7790 } |
| 7684 | 7791 |
| 7685 AssertNoAllocation no_alloc; | 7792 AssertNoAllocation no_alloc; |
| 7686 | 7793 |
| 7687 // Split elements into defined, undefined and the_hole, in that order. | 7794 // Split elements into defined, undefined and the_hole, in that order. |
| 7688 // Only count locations for undefined and the hole, and fill them afterwards. | 7795 // Only count locations for undefined and the hole, and fill them afterwards. |
| 7689 WriteBarrierMode write_barrier = elements->GetWriteBarrierMode(no_alloc); | 7796 WriteBarrierMode write_barrier = elements->GetWriteBarrierMode(no_alloc); |
| 7690 unsigned int undefs = limit; | 7797 unsigned int undefs = limit; |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 7763 // converted to a number type further up in the call chain. | 7870 // converted to a number type further up in the call chain. |
| 7764 ASSERT(value->IsUndefined()); | 7871 ASSERT(value->IsUndefined()); |
| 7765 } | 7872 } |
| 7766 set(index, clamped_value); | 7873 set(index, clamped_value); |
| 7767 } | 7874 } |
| 7768 return Smi::FromInt(clamped_value); | 7875 return Smi::FromInt(clamped_value); |
| 7769 } | 7876 } |
| 7770 | 7877 |
| 7771 | 7878 |
| 7772 template<typename ExternalArrayClass, typename ValueType> | 7879 template<typename ExternalArrayClass, typename ValueType> |
| 7773 static Object* ExternalArrayIntSetter(ExternalArrayClass* receiver, | 7880 static Object* ExternalArrayIntSetter(Heap* heap, |
| 7881 ExternalArrayClass* receiver, |
| 7774 uint32_t index, | 7882 uint32_t index, |
| 7775 Object* value) { | 7883 Object* value) { |
| 7776 ValueType cast_value = 0; | 7884 ValueType cast_value = 0; |
| 7777 if (index < static_cast<uint32_t>(receiver->length())) { | 7885 if (index < static_cast<uint32_t>(receiver->length())) { |
| 7778 if (value->IsSmi()) { | 7886 if (value->IsSmi()) { |
| 7779 int int_value = Smi::cast(value)->value(); | 7887 int int_value = Smi::cast(value)->value(); |
| 7780 cast_value = static_cast<ValueType>(int_value); | 7888 cast_value = static_cast<ValueType>(int_value); |
| 7781 } else if (value->IsHeapNumber()) { | 7889 } else if (value->IsHeapNumber()) { |
| 7782 double double_value = HeapNumber::cast(value)->value(); | 7890 double double_value = HeapNumber::cast(value)->value(); |
| 7783 cast_value = static_cast<ValueType>(DoubleToInt32(double_value)); | 7891 cast_value = static_cast<ValueType>(DoubleToInt32(double_value)); |
| 7784 } else { | 7892 } else { |
| 7785 // Clamp undefined to zero (default). All other types have been | 7893 // Clamp undefined to zero (default). All other types have been |
| 7786 // converted to a number type further up in the call chain. | 7894 // converted to a number type further up in the call chain. |
| 7787 ASSERT(value->IsUndefined()); | 7895 ASSERT(value->IsUndefined()); |
| 7788 } | 7896 } |
| 7789 receiver->set(index, cast_value); | 7897 receiver->set(index, cast_value); |
| 7790 } | 7898 } |
| 7791 return HEAP->NumberFromInt32(cast_value); | 7899 return heap->NumberFromInt32(cast_value); |
| 7792 } | 7900 } |
| 7793 | 7901 |
| 7794 | 7902 |
| 7795 Object* ExternalByteArray::SetValue(uint32_t index, Object* value) { | 7903 Object* ExternalByteArray::SetValue(uint32_t index, Object* value) { |
| 7796 return ExternalArrayIntSetter<ExternalByteArray, int8_t> | 7904 return ExternalArrayIntSetter<ExternalByteArray, int8_t> |
| 7797 (this, index, value); | 7905 (GetHeap(), this, index, value); |
| 7798 } | 7906 } |
| 7799 | 7907 |
| 7800 | 7908 |
| 7801 Object* ExternalUnsignedByteArray::SetValue(uint32_t index, Object* value) { | 7909 Object* ExternalUnsignedByteArray::SetValue(uint32_t index, Object* value) { |
| 7802 return ExternalArrayIntSetter<ExternalUnsignedByteArray, uint8_t> | 7910 return ExternalArrayIntSetter<ExternalUnsignedByteArray, uint8_t> |
| 7803 (this, index, value); | 7911 (GetHeap(), this, index, value); |
| 7804 } | 7912 } |
| 7805 | 7913 |
| 7806 | 7914 |
| 7807 Object* ExternalShortArray::SetValue(uint32_t index, Object* value) { | 7915 Object* ExternalShortArray::SetValue(uint32_t index, Object* value) { |
| 7808 return ExternalArrayIntSetter<ExternalShortArray, int16_t> | 7916 return ExternalArrayIntSetter<ExternalShortArray, int16_t> |
| 7809 (this, index, value); | 7917 (GetHeap(), this, index, value); |
| 7810 } | 7918 } |
| 7811 | 7919 |
| 7812 | 7920 |
| 7813 Object* ExternalUnsignedShortArray::SetValue(uint32_t index, Object* value) { | 7921 Object* ExternalUnsignedShortArray::SetValue(uint32_t index, Object* value) { |
| 7814 return ExternalArrayIntSetter<ExternalUnsignedShortArray, uint16_t> | 7922 return ExternalArrayIntSetter<ExternalUnsignedShortArray, uint16_t> |
| 7815 (this, index, value); | 7923 (GetHeap(), this, index, value); |
| 7816 } | 7924 } |
| 7817 | 7925 |
| 7818 | 7926 |
| 7819 Object* ExternalIntArray::SetValue(uint32_t index, Object* value) { | 7927 Object* ExternalIntArray::SetValue(uint32_t index, Object* value) { |
| 7820 return ExternalArrayIntSetter<ExternalIntArray, int32_t> | 7928 return ExternalArrayIntSetter<ExternalIntArray, int32_t> |
| 7821 (this, index, value); | 7929 (GetHeap(), this, index, value); |
| 7822 } | 7930 } |
| 7823 | 7931 |
| 7824 | 7932 |
| 7825 Object* ExternalUnsignedIntArray::SetValue(uint32_t index, Object* value) { | 7933 Object* ExternalUnsignedIntArray::SetValue(uint32_t index, Object* value) { |
| 7826 uint32_t cast_value = 0; | 7934 uint32_t cast_value = 0; |
| 7935 Heap* heap = GetHeap(); |
| 7827 if (index < static_cast<uint32_t>(length())) { | 7936 if (index < static_cast<uint32_t>(length())) { |
| 7828 if (value->IsSmi()) { | 7937 if (value->IsSmi()) { |
| 7829 int int_value = Smi::cast(value)->value(); | 7938 int int_value = Smi::cast(value)->value(); |
| 7830 cast_value = static_cast<uint32_t>(int_value); | 7939 cast_value = static_cast<uint32_t>(int_value); |
| 7831 } else if (value->IsHeapNumber()) { | 7940 } else if (value->IsHeapNumber()) { |
| 7832 double double_value = HeapNumber::cast(value)->value(); | 7941 double double_value = HeapNumber::cast(value)->value(); |
| 7833 cast_value = static_cast<uint32_t>(DoubleToUint32(double_value)); | 7942 cast_value = static_cast<uint32_t>(DoubleToUint32(double_value)); |
| 7834 } else { | 7943 } else { |
| 7835 // Clamp undefined to zero (default). All other types have been | 7944 // Clamp undefined to zero (default). All other types have been |
| 7836 // converted to a number type further up in the call chain. | 7945 // converted to a number type further up in the call chain. |
| 7837 ASSERT(value->IsUndefined()); | 7946 ASSERT(value->IsUndefined()); |
| 7838 } | 7947 } |
| 7839 set(index, cast_value); | 7948 set(index, cast_value); |
| 7840 } | 7949 } |
| 7841 return HEAP->NumberFromUint32(cast_value); | 7950 return heap->NumberFromUint32(cast_value); |
| 7842 } | 7951 } |
| 7843 | 7952 |
| 7844 | 7953 |
| 7845 Object* ExternalFloatArray::SetValue(uint32_t index, Object* value) { | 7954 Object* ExternalFloatArray::SetValue(uint32_t index, Object* value) { |
| 7846 float cast_value = 0; | 7955 float cast_value = 0; |
| 7956 Heap* heap = GetHeap(); |
| 7847 if (index < static_cast<uint32_t>(length())) { | 7957 if (index < static_cast<uint32_t>(length())) { |
| 7848 if (value->IsSmi()) { | 7958 if (value->IsSmi()) { |
| 7849 int int_value = Smi::cast(value)->value(); | 7959 int int_value = Smi::cast(value)->value(); |
| 7850 cast_value = static_cast<float>(int_value); | 7960 cast_value = static_cast<float>(int_value); |
| 7851 } else if (value->IsHeapNumber()) { | 7961 } else if (value->IsHeapNumber()) { |
| 7852 double double_value = HeapNumber::cast(value)->value(); | 7962 double double_value = HeapNumber::cast(value)->value(); |
| 7853 cast_value = static_cast<float>(double_value); | 7963 cast_value = static_cast<float>(double_value); |
| 7854 } else { | 7964 } else { |
| 7855 // Clamp undefined to zero (default). All other types have been | 7965 // Clamp undefined to zero (default). All other types have been |
| 7856 // converted to a number type further up in the call chain. | 7966 // converted to a number type further up in the call chain. |
| 7857 ASSERT(value->IsUndefined()); | 7967 ASSERT(value->IsUndefined()); |
| 7858 } | 7968 } |
| 7859 set(index, cast_value); | 7969 set(index, cast_value); |
| 7860 } | 7970 } |
| 7861 return HEAP->AllocateHeapNumber(cast_value); | 7971 return heap->AllocateHeapNumber(cast_value); |
| 7862 } | 7972 } |
| 7863 | 7973 |
| 7864 | 7974 |
| 7865 Object* GlobalObject::GetPropertyCell(LookupResult* result) { | 7975 Object* GlobalObject::GetPropertyCell(LookupResult* result) { |
| 7866 ASSERT(!HasFastProperties()); | 7976 ASSERT(!HasFastProperties()); |
| 7867 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); | 7977 Object* value = property_dictionary()->ValueAt(result->GetDictionaryEntry()); |
| 7868 ASSERT(value->IsJSGlobalPropertyCell()); | 7978 ASSERT(value->IsJSGlobalPropertyCell()); |
| 7869 return value; | 7979 return value; |
| 7870 } | 7980 } |
| 7871 | 7981 |
| 7872 | 7982 |
| 7873 Object* GlobalObject::EnsurePropertyCell(String* name) { | 7983 Object* GlobalObject::EnsurePropertyCell(String* name) { |
| 7874 ASSERT(!HasFastProperties()); | 7984 ASSERT(!HasFastProperties()); |
| 7985 Heap* heap = GetHeap(); |
| 7875 int entry = property_dictionary()->FindEntry(name); | 7986 int entry = property_dictionary()->FindEntry(name); |
| 7876 if (entry == StringDictionary::kNotFound) { | 7987 if (entry == StringDictionary::kNotFound) { |
| 7877 Object* cell = HEAP->AllocateJSGlobalPropertyCell(HEAP->the_hole_value()); | 7988 Object* cell = heap->AllocateJSGlobalPropertyCell(heap->the_hole_value()); |
| 7878 if (cell->IsFailure()) return cell; | 7989 if (cell->IsFailure()) return cell; |
| 7879 PropertyDetails details(NONE, NORMAL); | 7990 PropertyDetails details(NONE, NORMAL); |
| 7880 details = details.AsDeleted(); | 7991 details = details.AsDeleted(); |
| 7881 Object* dictionary = property_dictionary()->Add(name, cell, details); | 7992 Object* dictionary = property_dictionary()->Add(name, cell, details); |
| 7882 if (dictionary->IsFailure()) return dictionary; | 7993 if (dictionary->IsFailure()) return dictionary; |
| 7883 set_properties(StringDictionary::cast(dictionary)); | 7994 set_properties(StringDictionary::cast(dictionary)); |
| 7884 return cell; | 7995 return cell; |
| 7885 } else { | 7996 } else { |
| 7886 Object* value = property_dictionary()->ValueAt(entry); | 7997 Object* value = property_dictionary()->ValueAt(entry); |
| 7887 ASSERT(value->IsJSGlobalPropertyCell()); | 7998 ASSERT(value->IsJSGlobalPropertyCell()); |
| (...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8018 // Add the new symbol and return it along with the symbol table. | 8129 // Add the new symbol and return it along with the symbol table. |
| 8019 entry = table->FindInsertionEntry(key->Hash()); | 8130 entry = table->FindInsertionEntry(key->Hash()); |
| 8020 table->set(EntryToIndex(entry), symbol); | 8131 table->set(EntryToIndex(entry), symbol); |
| 8021 table->ElementAdded(); | 8132 table->ElementAdded(); |
| 8022 *s = symbol; | 8133 *s = symbol; |
| 8023 return table; | 8134 return table; |
| 8024 } | 8135 } |
| 8025 | 8136 |
| 8026 | 8137 |
| 8027 Object* CompilationCacheTable::Lookup(String* src) { | 8138 Object* CompilationCacheTable::Lookup(String* src) { |
| 8139 Heap* heap = GetHeap(); |
| 8028 StringKey key(src); | 8140 StringKey key(src); |
| 8029 int entry = FindEntry(&key); | 8141 int entry = FindEntry(&key); |
| 8030 if (entry == kNotFound) return HEAP->undefined_value(); | 8142 if (entry == kNotFound) return heap->undefined_value(); |
| 8031 return get(EntryToIndex(entry) + 1); | 8143 return get(EntryToIndex(entry) + 1); |
| 8032 } | 8144 } |
| 8033 | 8145 |
| 8034 | 8146 |
| 8035 Object* CompilationCacheTable::LookupEval(String* src, Context* context) { | 8147 Object* CompilationCacheTable::LookupEval(String* src, Context* context) { |
| 8036 StringSharedKey key(src, context->closure()->shared()); | 8148 StringSharedKey key(src, context->closure()->shared()); |
| 8037 int entry = FindEntry(&key); | 8149 int entry = FindEntry(&key); |
| 8038 if (entry == kNotFound) return HEAP->undefined_value(); | 8150 if (entry == kNotFound) return GetHeap()->undefined_value(); |
| 8039 return get(EntryToIndex(entry) + 1); | 8151 return get(EntryToIndex(entry) + 1); |
| 8040 } | 8152 } |
| 8041 | 8153 |
| 8042 | 8154 |
| 8043 Object* CompilationCacheTable::LookupRegExp(String* src, | 8155 Object* CompilationCacheTable::LookupRegExp(String* src, |
| 8044 JSRegExp::Flags flags) { | 8156 JSRegExp::Flags flags) { |
| 8157 Heap* heap = GetHeap(); |
| 8045 RegExpKey key(src, flags); | 8158 RegExpKey key(src, flags); |
| 8046 int entry = FindEntry(&key); | 8159 int entry = FindEntry(&key); |
| 8047 if (entry == kNotFound) return HEAP->undefined_value(); | 8160 if (entry == kNotFound) return heap->undefined_value(); |
| 8048 return get(EntryToIndex(entry) + 1); | 8161 return get(EntryToIndex(entry) + 1); |
| 8049 } | 8162 } |
| 8050 | 8163 |
| 8051 | 8164 |
| 8052 Object* CompilationCacheTable::Put(String* src, Object* value) { | 8165 Object* CompilationCacheTable::Put(String* src, Object* value) { |
| 8053 StringKey key(src); | 8166 StringKey key(src); |
| 8054 Object* obj = EnsureCapacity(1, &key); | 8167 Object* obj = EnsureCapacity(1, &key); |
| 8055 if (obj->IsFailure()) return obj; | 8168 if (obj->IsFailure()) return obj; |
| 8056 | 8169 |
| 8057 CompilationCacheTable* cache = | 8170 CompilationCacheTable* cache = |
| (...skipping 74 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8132 } | 8245 } |
| 8133 | 8246 |
| 8134 Object* AsObject() { return symbols_; } | 8247 Object* AsObject() { return symbols_; } |
| 8135 | 8248 |
| 8136 private: | 8249 private: |
| 8137 FixedArray* symbols_; | 8250 FixedArray* symbols_; |
| 8138 }; | 8251 }; |
| 8139 | 8252 |
| 8140 | 8253 |
| 8141 Object* MapCache::Lookup(FixedArray* array) { | 8254 Object* MapCache::Lookup(FixedArray* array) { |
| 8255 Heap* heap = GetHeap(); |
| 8142 SymbolsKey key(array); | 8256 SymbolsKey key(array); |
| 8143 int entry = FindEntry(&key); | 8257 int entry = FindEntry(&key); |
| 8144 if (entry == kNotFound) return HEAP->undefined_value(); | 8258 if (entry == kNotFound) return heap->undefined_value(); |
| 8145 return get(EntryToIndex(entry) + 1); | 8259 return get(EntryToIndex(entry) + 1); |
| 8146 } | 8260 } |
| 8147 | 8261 |
| 8148 | 8262 |
| 8149 Object* MapCache::Put(FixedArray* array, Map* value) { | 8263 Object* MapCache::Put(FixedArray* array, Map* value) { |
| 8150 SymbolsKey key(array); | 8264 SymbolsKey key(array); |
| 8151 Object* obj = EnsureCapacity(1, &key); | 8265 Object* obj = EnsureCapacity(1, &key); |
| 8152 if (obj->IsFailure()) return obj; | 8266 if (obj->IsFailure()) return obj; |
| 8153 | 8267 |
| 8154 MapCache* cache = reinterpret_cast<MapCache*>(obj); | 8268 MapCache* cache = reinterpret_cast<MapCache*>(obj); |
| (...skipping 12 matching lines...) Expand all Loading... |
| 8167 if (!obj->IsFailure()) { | 8281 if (!obj->IsFailure()) { |
| 8168 Dictionary<Shape, Key>::cast(obj)-> | 8282 Dictionary<Shape, Key>::cast(obj)-> |
| 8169 SetNextEnumerationIndex(PropertyDetails::kInitialIndex); | 8283 SetNextEnumerationIndex(PropertyDetails::kInitialIndex); |
| 8170 } | 8284 } |
| 8171 return obj; | 8285 return obj; |
| 8172 } | 8286 } |
| 8173 | 8287 |
| 8174 | 8288 |
| 8175 template<typename Shape, typename Key> | 8289 template<typename Shape, typename Key> |
| 8176 Object* Dictionary<Shape, Key>::GenerateNewEnumerationIndices() { | 8290 Object* Dictionary<Shape, Key>::GenerateNewEnumerationIndices() { |
| 8291 Heap* heap = Dictionary<Shape, Key>::GetHeap(); |
| 8177 int length = HashTable<Shape, Key>::NumberOfElements(); | 8292 int length = HashTable<Shape, Key>::NumberOfElements(); |
| 8178 | 8293 |
| 8179 // Allocate and initialize iteration order array. | 8294 // Allocate and initialize iteration order array. |
| 8180 Object* obj = HEAP->AllocateFixedArray(length); | 8295 Object* obj = heap->AllocateFixedArray(length); |
| 8181 if (obj->IsFailure()) return obj; | 8296 if (obj->IsFailure()) return obj; |
| 8182 FixedArray* iteration_order = FixedArray::cast(obj); | 8297 FixedArray* iteration_order = FixedArray::cast(obj); |
| 8183 for (int i = 0; i < length; i++) { | 8298 for (int i = 0; i < length; i++) { |
| 8184 iteration_order->set(i, Smi::FromInt(i)); | 8299 iteration_order->set(i, Smi::FromInt(i)); |
| 8185 } | 8300 } |
| 8186 | 8301 |
| 8187 // Allocate array with enumeration order. | 8302 // Allocate array with enumeration order. |
| 8188 obj = HEAP->AllocateFixedArray(length); | 8303 obj = heap->AllocateFixedArray(length); |
| 8189 if (obj->IsFailure()) return obj; | 8304 if (obj->IsFailure()) return obj; |
| 8190 FixedArray* enumeration_order = FixedArray::cast(obj); | 8305 FixedArray* enumeration_order = FixedArray::cast(obj); |
| 8191 | 8306 |
| 8192 // Fill the enumeration order array with property details. | 8307 // Fill the enumeration order array with property details. |
| 8193 int capacity = HashTable<Shape, Key>::Capacity(); | 8308 int capacity = HashTable<Shape, Key>::Capacity(); |
| 8194 int pos = 0; | 8309 int pos = 0; |
| 8195 for (int i = 0; i < capacity; i++) { | 8310 for (int i = 0; i < capacity; i++) { |
| 8196 if (Dictionary<Shape, Key>::IsKey(Dictionary<Shape, Key>::KeyAt(i))) { | 8311 if (Dictionary<Shape, Key>::IsKey(Dictionary<Shape, Key>::KeyAt(i))) { |
| 8197 enumeration_order->set(pos++, Smi::FromInt(DetailsAt(i).index())); | 8312 enumeration_order->set(pos++, Smi::FromInt(DetailsAt(i).index())); |
| 8198 } | 8313 } |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8236 if (result->IsFailure()) return result; | 8351 if (result->IsFailure()) return result; |
| 8237 } | 8352 } |
| 8238 return HashTable<Shape, Key>::EnsureCapacity(n, key); | 8353 return HashTable<Shape, Key>::EnsureCapacity(n, key); |
| 8239 } | 8354 } |
| 8240 | 8355 |
| 8241 | 8356 |
| 8242 void NumberDictionary::RemoveNumberEntries(uint32_t from, uint32_t to) { | 8357 void NumberDictionary::RemoveNumberEntries(uint32_t from, uint32_t to) { |
| 8243 // Do nothing if the interval [from, to) is empty. | 8358 // Do nothing if the interval [from, to) is empty. |
| 8244 if (from >= to) return; | 8359 if (from >= to) return; |
| 8245 | 8360 |
| 8361 Heap* heap = GetHeap(); |
| 8246 int removed_entries = 0; | 8362 int removed_entries = 0; |
| 8247 Object* sentinel = HEAP->null_value(); | 8363 Object* sentinel = heap->null_value(); |
| 8248 int capacity = Capacity(); | 8364 int capacity = Capacity(); |
| 8249 for (int i = 0; i < capacity; i++) { | 8365 for (int i = 0; i < capacity; i++) { |
| 8250 Object* key = KeyAt(i); | 8366 Object* key = KeyAt(i); |
| 8251 if (key->IsNumber()) { | 8367 if (key->IsNumber()) { |
| 8252 uint32_t number = static_cast<uint32_t>(key->Number()); | 8368 uint32_t number = static_cast<uint32_t>(key->Number()); |
| 8253 if (from <= number && number < to) { | 8369 if (from <= number && number < to) { |
| 8254 SetEntry(i, sentinel, sentinel, Smi::FromInt(0)); | 8370 SetEntry(i, sentinel, sentinel, Smi::FromInt(0)); |
| 8255 removed_entries++; | 8371 removed_entries++; |
| 8256 } | 8372 } |
| 8257 } | 8373 } |
| 8258 } | 8374 } |
| 8259 | 8375 |
| 8260 // Update the number of elements. | 8376 // Update the number of elements. |
| 8261 ElementsRemoved(removed_entries); | 8377 ElementsRemoved(removed_entries); |
| 8262 } | 8378 } |
| 8263 | 8379 |
| 8264 | 8380 |
| 8265 template<typename Shape, typename Key> | 8381 template<typename Shape, typename Key> |
| 8266 Object* Dictionary<Shape, Key>::DeleteProperty(int entry, | 8382 Object* Dictionary<Shape, Key>::DeleteProperty(int entry, |
| 8267 JSObject::DeleteMode mode) { | 8383 JSObject::DeleteMode mode) { |
| 8384 Heap* heap = Dictionary<Shape, Key>::GetHeap(); |
| 8268 PropertyDetails details = DetailsAt(entry); | 8385 PropertyDetails details = DetailsAt(entry); |
| 8269 // Ignore attributes if forcing a deletion. | 8386 // Ignore attributes if forcing a deletion. |
| 8270 if (details.IsDontDelete() && mode == JSObject::NORMAL_DELETION) { | 8387 if (details.IsDontDelete() && mode == JSObject::NORMAL_DELETION) { |
| 8271 return HEAP->false_value(); | 8388 return heap->false_value(); |
| 8272 } | 8389 } |
| 8273 SetEntry(entry, HEAP->null_value(), HEAP->null_value(), Smi::FromInt(0)); | 8390 SetEntry(entry, heap->null_value(), heap->null_value(), Smi::FromInt(0)); |
| 8274 HashTable<Shape, Key>::ElementRemoved(); | 8391 HashTable<Shape, Key>::ElementRemoved(); |
| 8275 return HEAP->true_value(); | 8392 return heap->true_value(); |
| 8276 } | 8393 } |
| 8277 | 8394 |
| 8278 | 8395 |
| 8279 template<typename Shape, typename Key> | 8396 template<typename Shape, typename Key> |
| 8280 Object* Dictionary<Shape, Key>::AtPut(Key key, Object* value) { | 8397 Object* Dictionary<Shape, Key>::AtPut(Key key, Object* value) { |
| 8281 int entry = this->FindEntry(key); | 8398 int entry = this->FindEntry(key); |
| 8282 | 8399 |
| 8283 // If the entry is present set the value; | 8400 // If the entry is present set the value; |
| 8284 if (entry != Dictionary<Shape, Key>::kNotFound) { | 8401 if (entry != Dictionary<Shape, Key>::kNotFound) { |
| 8285 ValueAtPut(entry, value); | 8402 ValueAtPut(entry, value); |
| (...skipping 181 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8467 storage->set(index++, k); | 8584 storage->set(index++, k); |
| 8468 } | 8585 } |
| 8469 } | 8586 } |
| 8470 ASSERT(storage->length() >= index); | 8587 ASSERT(storage->length() >= index); |
| 8471 } | 8588 } |
| 8472 | 8589 |
| 8473 | 8590 |
| 8474 // Backwards lookup (slow). | 8591 // Backwards lookup (slow). |
| 8475 template<typename Shape, typename Key> | 8592 template<typename Shape, typename Key> |
| 8476 Object* Dictionary<Shape, Key>::SlowReverseLookup(Object* value) { | 8593 Object* Dictionary<Shape, Key>::SlowReverseLookup(Object* value) { |
| 8594 Heap* heap = Dictionary<Shape, Key>::GetHeap(); |
| 8477 int capacity = HashTable<Shape, Key>::Capacity(); | 8595 int capacity = HashTable<Shape, Key>::Capacity(); |
| 8478 for (int i = 0; i < capacity; i++) { | 8596 for (int i = 0; i < capacity; i++) { |
| 8479 Object* k = HashTable<Shape, Key>::KeyAt(i); | 8597 Object* k = HashTable<Shape, Key>::KeyAt(i); |
| 8480 if (Dictionary<Shape, Key>::IsKey(k)) { | 8598 if (Dictionary<Shape, Key>::IsKey(k)) { |
| 8481 Object* e = ValueAt(i); | 8599 Object* e = ValueAt(i); |
| 8482 if (e->IsJSGlobalPropertyCell()) { | 8600 if (e->IsJSGlobalPropertyCell()) { |
| 8483 e = JSGlobalPropertyCell::cast(e)->value(); | 8601 e = JSGlobalPropertyCell::cast(e)->value(); |
| 8484 } | 8602 } |
| 8485 if (e == value) return k; | 8603 if (e == value) return k; |
| 8486 } | 8604 } |
| 8487 } | 8605 } |
| 8488 return HEAP->undefined_value(); | 8606 return heap->undefined_value(); |
| 8489 } | 8607 } |
| 8490 | 8608 |
| 8491 | 8609 |
| 8492 Object* StringDictionary::TransformPropertiesToFastFor( | 8610 Object* StringDictionary::TransformPropertiesToFastFor( |
| 8493 JSObject* obj, int unused_property_fields) { | 8611 JSObject* obj, int unused_property_fields) { |
| 8612 Heap* heap = GetHeap(); |
| 8494 // Make sure we preserve dictionary representation if there are too many | 8613 // Make sure we preserve dictionary representation if there are too many |
| 8495 // descriptors. | 8614 // descriptors. |
| 8496 if (NumberOfElements() > DescriptorArray::kMaxNumberOfDescriptors) return obj; | 8615 if (NumberOfElements() > DescriptorArray::kMaxNumberOfDescriptors) return obj; |
| 8497 | 8616 |
| 8498 // Figure out if it is necessary to generate new enumeration indices. | 8617 // Figure out if it is necessary to generate new enumeration indices. |
| 8499 int max_enumeration_index = | 8618 int max_enumeration_index = |
| 8500 NextEnumerationIndex() + | 8619 NextEnumerationIndex() + |
| 8501 (DescriptorArray::kMaxNumberOfDescriptors - | 8620 (DescriptorArray::kMaxNumberOfDescriptors - |
| 8502 NumberOfElements()); | 8621 NumberOfElements()); |
| 8503 if (!PropertyDetails::IsValidIndex(max_enumeration_index)) { | 8622 if (!PropertyDetails::IsValidIndex(max_enumeration_index)) { |
| 8504 Object* result = GenerateNewEnumerationIndices(); | 8623 Object* result = GenerateNewEnumerationIndices(); |
| 8505 if (result->IsFailure()) return result; | 8624 if (result->IsFailure()) return result; |
| 8506 } | 8625 } |
| 8507 | 8626 |
| 8508 int instance_descriptor_length = 0; | 8627 int instance_descriptor_length = 0; |
| 8509 int number_of_fields = 0; | 8628 int number_of_fields = 0; |
| 8510 | 8629 |
| 8511 // Compute the length of the instance descriptor. | 8630 // Compute the length of the instance descriptor. |
| 8512 int capacity = Capacity(); | 8631 int capacity = Capacity(); |
| 8513 for (int i = 0; i < capacity; i++) { | 8632 for (int i = 0; i < capacity; i++) { |
| 8514 Object* k = KeyAt(i); | 8633 Object* k = KeyAt(i); |
| 8515 if (IsKey(k)) { | 8634 if (IsKey(k)) { |
| 8516 Object* value = ValueAt(i); | 8635 Object* value = ValueAt(i); |
| 8517 PropertyType type = DetailsAt(i).type(); | 8636 PropertyType type = DetailsAt(i).type(); |
| 8518 ASSERT(type != FIELD); | 8637 ASSERT(type != FIELD); |
| 8519 instance_descriptor_length++; | 8638 instance_descriptor_length++; |
| 8520 if (type == NORMAL && | 8639 if (type == NORMAL && |
| 8521 (!value->IsJSFunction() || HEAP->InNewSpace(value))) { | 8640 (!value->IsJSFunction() || heap->InNewSpace(value))) { |
| 8522 number_of_fields += 1; | 8641 number_of_fields += 1; |
| 8523 } | 8642 } |
| 8524 } | 8643 } |
| 8525 } | 8644 } |
| 8526 | 8645 |
| 8527 // Allocate the instance descriptor. | 8646 // Allocate the instance descriptor. |
| 8528 Object* descriptors_unchecked = | 8647 Object* descriptors_unchecked = |
| 8529 DescriptorArray::Allocate(instance_descriptor_length); | 8648 DescriptorArray::Allocate(instance_descriptor_length); |
| 8530 if (descriptors_unchecked->IsFailure()) return descriptors_unchecked; | 8649 if (descriptors_unchecked->IsFailure()) return descriptors_unchecked; |
| 8531 DescriptorArray* descriptors = DescriptorArray::cast(descriptors_unchecked); | 8650 DescriptorArray* descriptors = DescriptorArray::cast(descriptors_unchecked); |
| 8532 | 8651 |
| 8533 int inobject_props = obj->map()->inobject_properties(); | 8652 int inobject_props = obj->map()->inobject_properties(); |
| 8534 int number_of_allocated_fields = | 8653 int number_of_allocated_fields = |
| 8535 number_of_fields + unused_property_fields - inobject_props; | 8654 number_of_fields + unused_property_fields - inobject_props; |
| 8536 | 8655 |
| 8537 // Allocate the fixed array for the fields. | 8656 // Allocate the fixed array for the fields. |
| 8538 Object* fields = HEAP->AllocateFixedArray(number_of_allocated_fields); | 8657 Object* fields = heap->AllocateFixedArray(number_of_allocated_fields); |
| 8539 if (fields->IsFailure()) return fields; | 8658 if (fields->IsFailure()) return fields; |
| 8540 | 8659 |
| 8541 // Fill in the instance descriptor and the fields. | 8660 // Fill in the instance descriptor and the fields. |
| 8542 int next_descriptor = 0; | 8661 int next_descriptor = 0; |
| 8543 int current_offset = 0; | 8662 int current_offset = 0; |
| 8544 for (int i = 0; i < capacity; i++) { | 8663 for (int i = 0; i < capacity; i++) { |
| 8545 Object* k = KeyAt(i); | 8664 Object* k = KeyAt(i); |
| 8546 if (IsKey(k)) { | 8665 if (IsKey(k)) { |
| 8547 Object* value = ValueAt(i); | 8666 Object* value = ValueAt(i); |
| 8548 // Ensure the key is a symbol before writing into the instance descriptor. | 8667 // Ensure the key is a symbol before writing into the instance descriptor. |
| 8549 Object* key = HEAP->LookupSymbol(String::cast(k)); | 8668 Object* key = heap->LookupSymbol(String::cast(k)); |
| 8550 if (key->IsFailure()) return key; | 8669 if (key->IsFailure()) return key; |
| 8551 PropertyDetails details = DetailsAt(i); | 8670 PropertyDetails details = DetailsAt(i); |
| 8552 PropertyType type = details.type(); | 8671 PropertyType type = details.type(); |
| 8553 | 8672 |
| 8554 if (value->IsJSFunction() && !HEAP->InNewSpace(value)) { | 8673 if (value->IsJSFunction() && !heap->InNewSpace(value)) { |
| 8555 ConstantFunctionDescriptor d(String::cast(key), | 8674 ConstantFunctionDescriptor d(String::cast(key), |
| 8556 JSFunction::cast(value), | 8675 JSFunction::cast(value), |
| 8557 details.attributes(), | 8676 details.attributes(), |
| 8558 details.index()); | 8677 details.index()); |
| 8559 descriptors->Set(next_descriptor++, &d); | 8678 descriptors->Set(next_descriptor++, &d); |
| 8560 } else if (type == NORMAL) { | 8679 } else if (type == NORMAL) { |
| 8561 if (current_offset < inobject_props) { | 8680 if (current_offset < inobject_props) { |
| 8562 obj->InObjectPropertyAtPut(current_offset, | 8681 obj->InObjectPropertyAtPut(current_offset, |
| 8563 value, | 8682 value, |
| 8564 UPDATE_WRITE_BARRIER); | 8683 UPDATE_WRITE_BARRIER); |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8613 | 8732 |
| 8614 // If there is no break point info object or no break points in the break | 8733 // If there is no break point info object or no break points in the break |
| 8615 // point info object there is no break point at this code position. | 8734 // point info object there is no break point at this code position. |
| 8616 if (break_point_info->IsUndefined()) return false; | 8735 if (break_point_info->IsUndefined()) return false; |
| 8617 return BreakPointInfo::cast(break_point_info)->GetBreakPointCount() > 0; | 8736 return BreakPointInfo::cast(break_point_info)->GetBreakPointCount() > 0; |
| 8618 } | 8737 } |
| 8619 | 8738 |
| 8620 | 8739 |
| 8621 // Get the break point info object for this code position. | 8740 // Get the break point info object for this code position. |
| 8622 Object* DebugInfo::GetBreakPointInfo(int code_position) { | 8741 Object* DebugInfo::GetBreakPointInfo(int code_position) { |
| 8742 Heap* heap = GetHeap(); |
| 8623 // Find the index of the break point info object for this code position. | 8743 // Find the index of the break point info object for this code position. |
| 8624 int index = GetBreakPointInfoIndex(code_position); | 8744 int index = GetBreakPointInfoIndex(code_position); |
| 8625 | 8745 |
| 8626 // Return the break point info object if any. | 8746 // Return the break point info object if any. |
| 8627 if (index == kNoBreakPointInfo) return HEAP->undefined_value(); | 8747 if (index == kNoBreakPointInfo) return heap->undefined_value(); |
| 8628 return BreakPointInfo::cast(break_points()->get(index)); | 8748 return BreakPointInfo::cast(break_points()->get(index)); |
| 8629 } | 8749 } |
| 8630 | 8750 |
| 8631 | 8751 |
| 8632 // Clear a break point at the specified code position. | 8752 // Clear a break point at the specified code position. |
| 8633 void DebugInfo::ClearBreakPoint(Handle<DebugInfo> debug_info, | 8753 void DebugInfo::ClearBreakPoint(Handle<DebugInfo> debug_info, |
| 8634 int code_position, | 8754 int code_position, |
| 8635 Handle<Object> break_point_object) { | 8755 Handle<Object> break_point_object) { |
| 8636 Handle<Object> break_point_info(debug_info->GetBreakPointInfo(code_position)); | 8756 Handle<Object> break_point_info(debug_info->GetBreakPointInfo(code_position)); |
| 8637 if (break_point_info->IsUndefined()) return; | 8757 if (break_point_info->IsUndefined()) return; |
| 8638 BreakPointInfo::ClearBreakPoint( | 8758 BreakPointInfo::ClearBreakPoint( |
| 8639 Handle<BreakPointInfo>::cast(break_point_info), | 8759 Handle<BreakPointInfo>::cast(break_point_info), |
| 8640 break_point_object); | 8760 break_point_object); |
| 8641 } | 8761 } |
| 8642 | 8762 |
| 8643 | 8763 |
| 8644 void DebugInfo::SetBreakPoint(Handle<DebugInfo> debug_info, | 8764 void DebugInfo::SetBreakPoint(Handle<DebugInfo> debug_info, |
| 8645 int code_position, | 8765 int code_position, |
| 8646 int source_position, | 8766 int source_position, |
| 8647 int statement_position, | 8767 int statement_position, |
| 8648 Handle<Object> break_point_object) { | 8768 Handle<Object> break_point_object) { |
| 8769 Heap* heap = Isolate::Current()->heap(); |
| 8649 Handle<Object> break_point_info(debug_info->GetBreakPointInfo(code_position)); | 8770 Handle<Object> break_point_info(debug_info->GetBreakPointInfo(code_position)); |
| 8650 if (!break_point_info->IsUndefined()) { | 8771 if (!break_point_info->IsUndefined()) { |
| 8651 BreakPointInfo::SetBreakPoint( | 8772 BreakPointInfo::SetBreakPoint( |
| 8652 Handle<BreakPointInfo>::cast(break_point_info), | 8773 Handle<BreakPointInfo>::cast(break_point_info), |
| 8653 break_point_object); | 8774 break_point_object); |
| 8654 return; | 8775 return; |
| 8655 } | 8776 } |
| 8656 | 8777 |
| 8657 // Adding a new break point for a code position which did not have any | 8778 // Adding a new break point for a code position which did not have any |
| 8658 // break points before. Try to find a free slot. | 8779 // break points before. Try to find a free slot. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 8679 } | 8800 } |
| 8680 ASSERT(index != kNoBreakPointInfo); | 8801 ASSERT(index != kNoBreakPointInfo); |
| 8681 | 8802 |
| 8682 // Allocate new BreakPointInfo object and set the break point. | 8803 // Allocate new BreakPointInfo object and set the break point. |
| 8683 Handle<BreakPointInfo> new_break_point_info = | 8804 Handle<BreakPointInfo> new_break_point_info = |
| 8684 Handle<BreakPointInfo>::cast(Factory::NewStruct(BREAK_POINT_INFO_TYPE)); | 8805 Handle<BreakPointInfo>::cast(Factory::NewStruct(BREAK_POINT_INFO_TYPE)); |
| 8685 new_break_point_info->set_code_position(Smi::FromInt(code_position)); | 8806 new_break_point_info->set_code_position(Smi::FromInt(code_position)); |
| 8686 new_break_point_info->set_source_position(Smi::FromInt(source_position)); | 8807 new_break_point_info->set_source_position(Smi::FromInt(source_position)); |
| 8687 new_break_point_info-> | 8808 new_break_point_info-> |
| 8688 set_statement_position(Smi::FromInt(statement_position)); | 8809 set_statement_position(Smi::FromInt(statement_position)); |
| 8689 new_break_point_info->set_break_point_objects(HEAP->undefined_value()); | 8810 new_break_point_info->set_break_point_objects(heap->undefined_value()); |
| 8690 BreakPointInfo::SetBreakPoint(new_break_point_info, break_point_object); | 8811 BreakPointInfo::SetBreakPoint(new_break_point_info, break_point_object); |
| 8691 debug_info->break_points()->set(index, *new_break_point_info); | 8812 debug_info->break_points()->set(index, *new_break_point_info); |
| 8692 } | 8813 } |
| 8693 | 8814 |
| 8694 | 8815 |
| 8695 // Get the break point objects for a code position. | 8816 // Get the break point objects for a code position. |
| 8696 Object* DebugInfo::GetBreakPointObjects(int code_position) { | 8817 Object* DebugInfo::GetBreakPointObjects(int code_position) { |
| 8818 Heap* heap = GetHeap(); |
| 8697 Object* break_point_info = GetBreakPointInfo(code_position); | 8819 Object* break_point_info = GetBreakPointInfo(code_position); |
| 8698 if (break_point_info->IsUndefined()) { | 8820 if (break_point_info->IsUndefined()) { |
| 8699 return HEAP->undefined_value(); | 8821 return heap->undefined_value(); |
| 8700 } | 8822 } |
| 8701 return BreakPointInfo::cast(break_point_info)->break_point_objects(); | 8823 return BreakPointInfo::cast(break_point_info)->break_point_objects(); |
| 8702 } | 8824 } |
| 8703 | 8825 |
| 8704 | 8826 |
| 8705 // Get the total number of break points. | 8827 // Get the total number of break points. |
| 8706 int DebugInfo::GetBreakPointCount() { | 8828 int DebugInfo::GetBreakPointCount() { |
| 8707 if (break_points()->IsUndefined()) return 0; | 8829 if (break_points()->IsUndefined()) return 0; |
| 8708 int count = 0; | 8830 int count = 0; |
| 8709 for (int i = 0; i < break_points()->length(); i++) { | 8831 for (int i = 0; i < break_points()->length(); i++) { |
| 8710 if (!break_points()->get(i)->IsUndefined()) { | 8832 if (!break_points()->get(i)->IsUndefined()) { |
| 8711 BreakPointInfo* break_point_info = | 8833 BreakPointInfo* break_point_info = |
| 8712 BreakPointInfo::cast(break_points()->get(i)); | 8834 BreakPointInfo::cast(break_points()->get(i)); |
| 8713 count += break_point_info->GetBreakPointCount(); | 8835 count += break_point_info->GetBreakPointCount(); |
| 8714 } | 8836 } |
| 8715 } | 8837 } |
| 8716 return count; | 8838 return count; |
| 8717 } | 8839 } |
| 8718 | 8840 |
| 8719 | 8841 |
| 8720 Object* DebugInfo::FindBreakPointInfo(Handle<DebugInfo> debug_info, | 8842 Object* DebugInfo::FindBreakPointInfo(Handle<DebugInfo> debug_info, |
| 8721 Handle<Object> break_point_object) { | 8843 Handle<Object> break_point_object) { |
| 8722 if (debug_info->break_points()->IsUndefined()) return HEAP->undefined_value(); | 8844 Heap* heap = Isolate::Current()->heap(); |
| 8845 if (debug_info->break_points()->IsUndefined()) return heap->undefined_value(); |
| 8723 for (int i = 0; i < debug_info->break_points()->length(); i++) { | 8846 for (int i = 0; i < debug_info->break_points()->length(); i++) { |
| 8724 if (!debug_info->break_points()->get(i)->IsUndefined()) { | 8847 if (!debug_info->break_points()->get(i)->IsUndefined()) { |
| 8725 Handle<BreakPointInfo> break_point_info = | 8848 Handle<BreakPointInfo> break_point_info = |
| 8726 Handle<BreakPointInfo>(BreakPointInfo::cast( | 8849 Handle<BreakPointInfo>(BreakPointInfo::cast( |
| 8727 debug_info->break_points()->get(i))); | 8850 debug_info->break_points()->get(i))); |
| 8728 if (BreakPointInfo::HasBreakPointObject(break_point_info, | 8851 if (BreakPointInfo::HasBreakPointObject(break_point_info, |
| 8729 break_point_object)) { | 8852 break_point_object)) { |
| 8730 return *break_point_info; | 8853 return *break_point_info; |
| 8731 } | 8854 } |
| 8732 } | 8855 } |
| 8733 } | 8856 } |
| 8734 return HEAP->undefined_value(); | 8857 return heap->undefined_value(); |
| 8735 } | 8858 } |
| 8736 | 8859 |
| 8737 | 8860 |
| 8738 // Find the index of the break point info object for the specified code | 8861 // Find the index of the break point info object for the specified code |
| 8739 // position. | 8862 // position. |
| 8740 int DebugInfo::GetBreakPointInfoIndex(int code_position) { | 8863 int DebugInfo::GetBreakPointInfoIndex(int code_position) { |
| 8741 if (break_points()->IsUndefined()) return kNoBreakPointInfo; | 8864 if (break_points()->IsUndefined()) return kNoBreakPointInfo; |
| 8742 for (int i = 0; i < break_points()->length(); i++) { | 8865 for (int i = 0; i < break_points()->length(); i++) { |
| 8743 if (!break_points()->get(i)->IsUndefined()) { | 8866 if (!break_points()->get(i)->IsUndefined()) { |
| 8744 BreakPointInfo* break_point_info = | 8867 BreakPointInfo* break_point_info = |
| 8745 BreakPointInfo::cast(break_points()->get(i)); | 8868 BreakPointInfo::cast(break_points()->get(i)); |
| 8746 if (break_point_info->code_position()->value() == code_position) { | 8869 if (break_point_info->code_position()->value() == code_position) { |
| 8747 return i; | 8870 return i; |
| 8748 } | 8871 } |
| 8749 } | 8872 } |
| 8750 } | 8873 } |
| 8751 return kNoBreakPointInfo; | 8874 return kNoBreakPointInfo; |
| 8752 } | 8875 } |
| 8753 | 8876 |
| 8754 | 8877 |
| 8755 // Remove the specified break point object. | 8878 // Remove the specified break point object. |
| 8756 void BreakPointInfo::ClearBreakPoint(Handle<BreakPointInfo> break_point_info, | 8879 void BreakPointInfo::ClearBreakPoint(Handle<BreakPointInfo> break_point_info, |
| 8757 Handle<Object> break_point_object) { | 8880 Handle<Object> break_point_object) { |
| 8881 Heap* heap = Isolate::Current()->heap(); |
| 8758 // If there are no break points just ignore. | 8882 // If there are no break points just ignore. |
| 8759 if (break_point_info->break_point_objects()->IsUndefined()) return; | 8883 if (break_point_info->break_point_objects()->IsUndefined()) return; |
| 8760 // If there is a single break point clear it if it is the same. | 8884 // If there is a single break point clear it if it is the same. |
| 8761 if (!break_point_info->break_point_objects()->IsFixedArray()) { | 8885 if (!break_point_info->break_point_objects()->IsFixedArray()) { |
| 8762 if (break_point_info->break_point_objects() == *break_point_object) { | 8886 if (break_point_info->break_point_objects() == *break_point_object) { |
| 8763 break_point_info->set_break_point_objects(HEAP->undefined_value()); | 8887 break_point_info->set_break_point_objects(heap->undefined_value()); |
| 8764 } | 8888 } |
| 8765 return; | 8889 return; |
| 8766 } | 8890 } |
| 8767 // If there are multiple break points shrink the array | 8891 // If there are multiple break points shrink the array |
| 8768 ASSERT(break_point_info->break_point_objects()->IsFixedArray()); | 8892 ASSERT(break_point_info->break_point_objects()->IsFixedArray()); |
| 8769 Handle<FixedArray> old_array = | 8893 Handle<FixedArray> old_array = |
| 8770 Handle<FixedArray>( | 8894 Handle<FixedArray>( |
| 8771 FixedArray::cast(break_point_info->break_point_objects())); | 8895 FixedArray::cast(break_point_info->break_point_objects())); |
| 8772 Handle<FixedArray> new_array = | 8896 Handle<FixedArray> new_array = |
| 8773 Factory::NewFixedArray(old_array->length() - 1); | 8897 Factory::NewFixedArray(old_array->length() - 1); |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 8846 if (break_point_objects()->IsUndefined()) return 0; | 8970 if (break_point_objects()->IsUndefined()) return 0; |
| 8847 // Single beak point. | 8971 // Single beak point. |
| 8848 if (!break_point_objects()->IsFixedArray()) return 1; | 8972 if (!break_point_objects()->IsFixedArray()) return 1; |
| 8849 // Multiple break points. | 8973 // Multiple break points. |
| 8850 return FixedArray::cast(break_point_objects())->length(); | 8974 return FixedArray::cast(break_point_objects())->length(); |
| 8851 } | 8975 } |
| 8852 #endif | 8976 #endif |
| 8853 | 8977 |
| 8854 | 8978 |
| 8855 } } // namespace v8::internal | 8979 } } // namespace v8::internal |
| OLD | NEW |