| OLD | NEW |
| 1 // Copyright 2009 the V8 project authors. All rights reserved. | 1 // Copyright 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 27 matching lines...) Expand all Loading... |
| 38 #include "natives.h" | 38 #include "natives.h" |
| 39 #include "runtime.h" | 39 #include "runtime.h" |
| 40 #include "string-search.h" | 40 #include "string-search.h" |
| 41 #include "stub-cache.h" | 41 #include "stub-cache.h" |
| 42 #include "vm-state-inl.h" | 42 #include "vm-state-inl.h" |
| 43 | 43 |
| 44 namespace v8 { | 44 namespace v8 { |
| 45 namespace internal { | 45 namespace internal { |
| 46 | 46 |
| 47 | 47 |
| 48 v8::ImplementationUtilities::HandleScopeData HandleScope::current_ = | |
| 49 { NULL, NULL, 0 }; | |
| 50 | |
| 51 | |
| 52 int HandleScope::NumberOfHandles() { | 48 int HandleScope::NumberOfHandles() { |
| 53 int n = HandleScopeImplementer::instance()->blocks()->length(); | 49 Isolate* isolate = Isolate::Current(); |
| 50 HandleScopeImplementer* impl = isolate->handle_scope_implementer(); |
| 51 int n = impl->blocks()->length(); |
| 54 if (n == 0) return 0; | 52 if (n == 0) return 0; |
| 55 return ((n - 1) * kHandleBlockSize) + static_cast<int>( | 53 return ((n - 1) * kHandleBlockSize) + static_cast<int>( |
| 56 (current_.next - HandleScopeImplementer::instance()->blocks()->last())); | 54 (isolate->handle_scope_data()->next - impl->blocks()->last())); |
| 57 } | 55 } |
| 58 | 56 |
| 59 | 57 |
| 60 Object** HandleScope::Extend() { | 58 Object** HandleScope::Extend() { |
| 61 Object** result = current_.next; | 59 Isolate* isolate = Isolate::Current(); |
| 60 v8::ImplementationUtilities::HandleScopeData* current = |
| 61 isolate->handle_scope_data(); |
| 62 | 62 |
| 63 ASSERT(result == current_.limit); | 63 Object** result = current->next; |
| 64 |
| 65 ASSERT(result == current->limit); |
| 64 // Make sure there's at least one scope on the stack and that the | 66 // Make sure there's at least one scope on the stack and that the |
| 65 // top of the scope stack isn't a barrier. | 67 // top of the scope stack isn't a barrier. |
| 66 if (current_.level == 0) { | 68 if (current->level == 0) { |
| 67 Utils::ReportApiFailure("v8::HandleScope::CreateHandle()", | 69 Utils::ReportApiFailure("v8::HandleScope::CreateHandle()", |
| 68 "Cannot create a handle without a HandleScope"); | 70 "Cannot create a handle without a HandleScope"); |
| 69 return NULL; | 71 return NULL; |
| 70 } | 72 } |
| 71 HandleScopeImplementer* impl = HandleScopeImplementer::instance(); | 73 HandleScopeImplementer* impl = isolate->handle_scope_implementer(); |
| 72 // If there's more room in the last block, we use that. This is used | 74 // If there's more room in the last block, we use that. This is used |
| 73 // for fast creation of scopes after scope barriers. | 75 // for fast creation of scopes after scope barriers. |
| 74 if (!impl->blocks()->is_empty()) { | 76 if (!impl->blocks()->is_empty()) { |
| 75 Object** limit = &impl->blocks()->last()[kHandleBlockSize]; | 77 Object** limit = &impl->blocks()->last()[kHandleBlockSize]; |
| 76 if (current_.limit != limit) { | 78 if (current->limit != limit) { |
| 77 current_.limit = limit; | 79 current->limit = limit; |
| 78 ASSERT(limit - current_.next < kHandleBlockSize); | 80 ASSERT(limit - current->next < kHandleBlockSize); |
| 79 } | 81 } |
| 80 } | 82 } |
| 81 | 83 |
| 82 // If we still haven't found a slot for the handle, we extend the | 84 // If we still haven't found a slot for the handle, we extend the |
| 83 // current handle scope by allocating a new handle block. | 85 // current handle scope by allocating a new handle block. |
| 84 if (result == current_.limit) { | 86 if (result == current->limit) { |
| 85 // If there's a spare block, use it for growing the current scope. | 87 // If there's a spare block, use it for growing the current scope. |
| 86 result = impl->GetSpareOrNewBlock(); | 88 result = impl->GetSpareOrNewBlock(); |
| 87 // Add the extension to the global list of blocks, but count the | 89 // Add the extension to the global list of blocks, but count the |
| 88 // extension as part of the current scope. | 90 // extension as part of the current scope. |
| 89 impl->blocks()->Add(result); | 91 impl->blocks()->Add(result); |
| 90 current_.limit = &result[kHandleBlockSize]; | 92 current->limit = &result[kHandleBlockSize]; |
| 91 } | 93 } |
| 92 | 94 |
| 93 return result; | 95 return result; |
| 94 } | 96 } |
| 95 | 97 |
| 96 | 98 |
| 97 void HandleScope::DeleteExtensions() { | 99 void HandleScope::DeleteExtensions(Isolate* isolate) { |
| 98 HandleScopeImplementer::instance()->DeleteExtensions(current_.limit); | 100 ASSERT(isolate == Isolate::Current()); |
| 101 v8::ImplementationUtilities::HandleScopeData* current = |
| 102 isolate->handle_scope_data(); |
| 103 isolate->handle_scope_implementer()->DeleteExtensions(current->limit); |
| 99 } | 104 } |
| 100 | 105 |
| 101 | 106 |
| 102 void HandleScope::ZapRange(Object** start, Object** end) { | 107 void HandleScope::ZapRange(Object** start, Object** end) { |
| 103 ASSERT(end - start <= kHandleBlockSize); | 108 ASSERT(end - start <= kHandleBlockSize); |
| 104 for (Object** p = start; p != end; p++) { | 109 for (Object** p = start; p != end; p++) { |
| 105 *reinterpret_cast<Address*>(p) = v8::internal::kHandleZapValue; | 110 *reinterpret_cast<Address*>(p) = v8::internal::kHandleZapValue; |
| 106 } | 111 } |
| 107 } | 112 } |
| 108 | 113 |
| 109 | 114 |
| 110 Address HandleScope::current_level_address() { | 115 Address HandleScope::current_level_address() { |
| 111 return reinterpret_cast<Address>(¤t_.level); | 116 return reinterpret_cast<Address>( |
| 117 &Isolate::Current()->handle_scope_data()->level); |
| 112 } | 118 } |
| 113 | 119 |
| 114 | 120 |
| 115 Address HandleScope::current_next_address() { | 121 Address HandleScope::current_next_address() { |
| 116 return reinterpret_cast<Address>(¤t_.next); | 122 return reinterpret_cast<Address>( |
| 123 &Isolate::Current()->handle_scope_data()->next); |
| 117 } | 124 } |
| 118 | 125 |
| 119 | 126 |
| 120 Address HandleScope::current_limit_address() { | 127 Address HandleScope::current_limit_address() { |
| 121 return reinterpret_cast<Address>(¤t_.limit); | 128 return reinterpret_cast<Address>( |
| 129 &Isolate::Current()->handle_scope_data()->limit); |
| 122 } | 130 } |
| 123 | 131 |
| 124 | 132 |
| 125 Handle<FixedArray> AddKeysFromJSArray(Handle<FixedArray> content, | 133 Handle<FixedArray> AddKeysFromJSArray(Handle<FixedArray> content, |
| 126 Handle<JSArray> array) { | 134 Handle<JSArray> array) { |
| 127 CALL_HEAP_FUNCTION(content->AddKeysFromJSArray(*array), FixedArray); | 135 CALL_HEAP_FUNCTION(content->GetHeap()->isolate(), |
| 136 content->AddKeysFromJSArray(*array), FixedArray); |
| 128 } | 137 } |
| 129 | 138 |
| 130 | 139 |
| 131 Handle<FixedArray> UnionOfKeys(Handle<FixedArray> first, | 140 Handle<FixedArray> UnionOfKeys(Handle<FixedArray> first, |
| 132 Handle<FixedArray> second) { | 141 Handle<FixedArray> second) { |
| 133 CALL_HEAP_FUNCTION(first->UnionOfKeys(*second), FixedArray); | 142 CALL_HEAP_FUNCTION(first->GetHeap()->isolate(), |
| 143 first->UnionOfKeys(*second), FixedArray); |
| 134 } | 144 } |
| 135 | 145 |
| 136 | 146 |
| 137 Handle<JSGlobalProxy> ReinitializeJSGlobalProxy( | 147 Handle<JSGlobalProxy> ReinitializeJSGlobalProxy( |
| 138 Handle<JSFunction> constructor, | 148 Handle<JSFunction> constructor, |
| 139 Handle<JSGlobalProxy> global) { | 149 Handle<JSGlobalProxy> global) { |
| 140 CALL_HEAP_FUNCTION(Heap::ReinitializeJSGlobalProxy(*constructor, *global), | 150 CALL_HEAP_FUNCTION( |
| 141 JSGlobalProxy); | 151 constructor->GetHeap()->isolate(), |
| 152 constructor->GetHeap()->ReinitializeJSGlobalProxy(*constructor, *global), |
| 153 JSGlobalProxy); |
| 142 } | 154 } |
| 143 | 155 |
| 144 | 156 |
| 145 void SetExpectedNofProperties(Handle<JSFunction> func, int nof) { | 157 void SetExpectedNofProperties(Handle<JSFunction> func, int nof) { |
| 146 // If objects constructed from this function exist then changing | 158 // If objects constructed from this function exist then changing |
| 147 // 'estimated_nof_properties' is dangerous since the previous value might | 159 // 'estimated_nof_properties' is dangerous since the previous value might |
| 148 // have been compiled into the fast construct stub. More over, the inobject | 160 // have been compiled into the fast construct stub. More over, the inobject |
| 149 // slack tracking logic might have adjusted the previous value, so even | 161 // slack tracking logic might have adjusted the previous value, so even |
| 150 // passing the same value is risky. | 162 // passing the same value is risky. |
| 151 if (func->shared()->live_objects_may_exist()) return; | 163 if (func->shared()->live_objects_may_exist()) return; |
| 152 | 164 |
| 153 func->shared()->set_expected_nof_properties(nof); | 165 func->shared()->set_expected_nof_properties(nof); |
| 154 if (func->has_initial_map()) { | 166 if (func->has_initial_map()) { |
| 155 Handle<Map> new_initial_map = | 167 Handle<Map> new_initial_map = |
| 156 Factory::CopyMapDropTransitions(Handle<Map>(func->initial_map())); | 168 func->GetIsolate()->factory()->CopyMapDropTransitions( |
| 169 Handle<Map>(func->initial_map())); |
| 157 new_initial_map->set_unused_property_fields(nof); | 170 new_initial_map->set_unused_property_fields(nof); |
| 158 func->set_initial_map(*new_initial_map); | 171 func->set_initial_map(*new_initial_map); |
| 159 } | 172 } |
| 160 } | 173 } |
| 161 | 174 |
| 162 | 175 |
| 163 void SetPrototypeProperty(Handle<JSFunction> func, Handle<JSObject> value) { | 176 void SetPrototypeProperty(Handle<JSFunction> func, Handle<JSObject> value) { |
| 164 CALL_HEAP_FUNCTION_VOID(func->SetPrototype(*value)); | 177 CALL_HEAP_FUNCTION_VOID(func->GetHeap()->isolate(), |
| 178 func->SetPrototype(*value)); |
| 165 } | 179 } |
| 166 | 180 |
| 167 | 181 |
| 168 static int ExpectedNofPropertiesFromEstimate(int estimate) { | 182 static int ExpectedNofPropertiesFromEstimate(int estimate) { |
| 169 // If no properties are added in the constructor, they are more likely | 183 // If no properties are added in the constructor, they are more likely |
| 170 // to be added later. | 184 // to be added later. |
| 171 if (estimate == 0) estimate = 2; | 185 if (estimate == 0) estimate = 2; |
| 172 | 186 |
| 173 // We do not shrink objects that go into a snapshot (yet), so we adjust | 187 // We do not shrink objects that go into a snapshot (yet), so we adjust |
| 174 // the estimate conservatively. | 188 // the estimate conservatively. |
| (...skipping 11 matching lines...) Expand all Loading... |
| 186 if (shared->live_objects_may_exist()) return; | 200 if (shared->live_objects_may_exist()) return; |
| 187 | 201 |
| 188 shared->set_expected_nof_properties( | 202 shared->set_expected_nof_properties( |
| 189 ExpectedNofPropertiesFromEstimate(estimate)); | 203 ExpectedNofPropertiesFromEstimate(estimate)); |
| 190 } | 204 } |
| 191 | 205 |
| 192 | 206 |
| 193 void NormalizeProperties(Handle<JSObject> object, | 207 void NormalizeProperties(Handle<JSObject> object, |
| 194 PropertyNormalizationMode mode, | 208 PropertyNormalizationMode mode, |
| 195 int expected_additional_properties) { | 209 int expected_additional_properties) { |
| 196 CALL_HEAP_FUNCTION_VOID(object->NormalizeProperties( | 210 CALL_HEAP_FUNCTION_VOID(object->GetHeap()->isolate(), |
| 197 mode, | 211 object->NormalizeProperties( |
| 198 expected_additional_properties)); | 212 mode, |
| 213 expected_additional_properties)); |
| 199 } | 214 } |
| 200 | 215 |
| 201 | 216 |
| 202 void NormalizeElements(Handle<JSObject> object) { | 217 void NormalizeElements(Handle<JSObject> object) { |
| 203 CALL_HEAP_FUNCTION_VOID(object->NormalizeElements()); | 218 CALL_HEAP_FUNCTION_VOID(object->GetHeap()->isolate(), |
| 219 object->NormalizeElements()); |
| 204 } | 220 } |
| 205 | 221 |
| 206 | 222 |
| 207 void TransformToFastProperties(Handle<JSObject> object, | 223 void TransformToFastProperties(Handle<JSObject> object, |
| 208 int unused_property_fields) { | 224 int unused_property_fields) { |
| 209 CALL_HEAP_FUNCTION_VOID( | 225 CALL_HEAP_FUNCTION_VOID( |
| 226 object->GetHeap()->isolate(), |
| 210 object->TransformToFastProperties(unused_property_fields)); | 227 object->TransformToFastProperties(unused_property_fields)); |
| 211 } | 228 } |
| 212 | 229 |
| 213 | 230 |
| 214 void NumberDictionarySet(Handle<NumberDictionary> dictionary, | 231 void NumberDictionarySet(Handle<NumberDictionary> dictionary, |
| 215 uint32_t index, | 232 uint32_t index, |
| 216 Handle<Object> value, | 233 Handle<Object> value, |
| 217 PropertyDetails details) { | 234 PropertyDetails details) { |
| 218 CALL_HEAP_FUNCTION_VOID(dictionary->Set(index, *value, details)); | 235 CALL_HEAP_FUNCTION_VOID(dictionary->GetIsolate(), |
| 236 dictionary->Set(index, *value, details)); |
| 219 } | 237 } |
| 220 | 238 |
| 221 | 239 |
| 222 void FlattenString(Handle<String> string) { | 240 void FlattenString(Handle<String> string) { |
| 223 CALL_HEAP_FUNCTION_VOID(string->TryFlatten()); | 241 CALL_HEAP_FUNCTION_VOID(string->GetIsolate(), string->TryFlatten()); |
| 224 } | 242 } |
| 225 | 243 |
| 226 | 244 |
| 227 Handle<String> FlattenGetString(Handle<String> string) { | 245 Handle<String> FlattenGetString(Handle<String> string) { |
| 228 CALL_HEAP_FUNCTION(string->TryFlatten(), String); | 246 CALL_HEAP_FUNCTION(string->GetIsolate(), string->TryFlatten(), String); |
| 229 } | 247 } |
| 230 | 248 |
| 231 | 249 |
| 232 Handle<Object> SetPrototype(Handle<JSFunction> function, | 250 Handle<Object> SetPrototype(Handle<JSFunction> function, |
| 233 Handle<Object> prototype) { | 251 Handle<Object> prototype) { |
| 234 ASSERT(function->should_have_prototype()); | 252 ASSERT(function->should_have_prototype()); |
| 235 CALL_HEAP_FUNCTION(Accessors::FunctionSetPrototype(*function, | 253 CALL_HEAP_FUNCTION(function->GetHeap()->isolate(), |
| 254 Accessors::FunctionSetPrototype(*function, |
| 236 *prototype, | 255 *prototype, |
| 237 NULL), | 256 NULL), |
| 238 Object); | 257 Object); |
| 239 } | 258 } |
| 240 | 259 |
| 241 | 260 |
| 242 Handle<Object> SetProperty(Handle<JSObject> object, | 261 Handle<Object> SetProperty(Handle<JSObject> object, |
| 243 Handle<String> key, | 262 Handle<String> key, |
| 244 Handle<Object> value, | 263 Handle<Object> value, |
| 245 PropertyAttributes attributes, | 264 PropertyAttributes attributes, |
| 246 StrictModeFlag strict_mode) { | 265 StrictModeFlag strict_mode) { |
| 247 CALL_HEAP_FUNCTION(object->SetProperty(*key, *value, attributes, strict_mode), | 266 CALL_HEAP_FUNCTION(object->GetHeap()->isolate(), |
| 267 object->SetProperty(*key, *value, attributes, strict_mode), |
| 248 Object); | 268 Object); |
| 249 } | 269 } |
| 250 | 270 |
| 251 | 271 |
| 252 Handle<Object> SetProperty(Handle<Object> object, | 272 Handle<Object> SetProperty(Handle<Object> object, |
| 253 Handle<Object> key, | 273 Handle<Object> key, |
| 254 Handle<Object> value, | 274 Handle<Object> value, |
| 255 PropertyAttributes attributes, | 275 PropertyAttributes attributes, |
| 256 StrictModeFlag strict_mode) { | 276 StrictModeFlag strict_mode) { |
| 277 Isolate* isolate = Isolate::Current(); |
| 257 CALL_HEAP_FUNCTION( | 278 CALL_HEAP_FUNCTION( |
| 258 Runtime::SetObjectProperty(object, key, value, attributes, strict_mode), | 279 isolate, |
| 280 Runtime::SetObjectProperty( |
| 281 isolate, object, key, value, attributes, strict_mode), |
| 259 Object); | 282 Object); |
| 260 } | 283 } |
| 261 | 284 |
| 262 | 285 |
| 263 Handle<Object> ForceSetProperty(Handle<JSObject> object, | 286 Handle<Object> ForceSetProperty(Handle<JSObject> object, |
| 264 Handle<Object> key, | 287 Handle<Object> key, |
| 265 Handle<Object> value, | 288 Handle<Object> value, |
| 266 PropertyAttributes attributes) { | 289 PropertyAttributes attributes) { |
| 290 Isolate* isolate = object->GetIsolate(); |
| 267 CALL_HEAP_FUNCTION( | 291 CALL_HEAP_FUNCTION( |
| 292 isolate, |
| 268 Runtime::ForceSetObjectProperty( | 293 Runtime::ForceSetObjectProperty( |
| 269 object, key, value, attributes), | 294 isolate, object, key, value, attributes), |
| 270 Object); | 295 Object); |
| 271 } | 296 } |
| 272 | 297 |
| 273 | 298 |
| 274 Handle<Object> SetNormalizedProperty(Handle<JSObject> object, | 299 Handle<Object> SetNormalizedProperty(Handle<JSObject> object, |
| 275 Handle<String> key, | 300 Handle<String> key, |
| 276 Handle<Object> value, | 301 Handle<Object> value, |
| 277 PropertyDetails details) { | 302 PropertyDetails details) { |
| 278 CALL_HEAP_FUNCTION(object->SetNormalizedProperty(*key, *value, details), | 303 CALL_HEAP_FUNCTION(object->GetIsolate(), |
| 304 object->SetNormalizedProperty(*key, *value, details), |
| 279 Object); | 305 Object); |
| 280 } | 306 } |
| 281 | 307 |
| 282 | 308 |
| 283 Handle<Object> ForceDeleteProperty(Handle<JSObject> object, | 309 Handle<Object> ForceDeleteProperty(Handle<JSObject> object, |
| 284 Handle<Object> key) { | 310 Handle<Object> key) { |
| 285 CALL_HEAP_FUNCTION(Runtime::ForceDeleteObjectProperty(object, key), Object); | 311 Isolate* isolate = object->GetIsolate(); |
| 312 CALL_HEAP_FUNCTION(isolate, |
| 313 Runtime::ForceDeleteObjectProperty(isolate, object, key), |
| 314 Object); |
| 286 } | 315 } |
| 287 | 316 |
| 288 | 317 |
| 289 Handle<Object> SetLocalPropertyIgnoreAttributes( | 318 Handle<Object> SetLocalPropertyIgnoreAttributes( |
| 290 Handle<JSObject> object, | 319 Handle<JSObject> object, |
| 291 Handle<String> key, | 320 Handle<String> key, |
| 292 Handle<Object> value, | 321 Handle<Object> value, |
| 293 PropertyAttributes attributes) { | 322 PropertyAttributes attributes) { |
| 294 CALL_HEAP_FUNCTION(object-> | 323 CALL_HEAP_FUNCTION( |
| 295 SetLocalPropertyIgnoreAttributes(*key, *value, attributes), Object); | 324 object->GetIsolate(), |
| 325 object->SetLocalPropertyIgnoreAttributes(*key, *value, attributes), |
| 326 Object); |
| 296 } | 327 } |
| 297 | 328 |
| 298 | 329 |
| 299 void SetLocalPropertyNoThrow(Handle<JSObject> object, | 330 void SetLocalPropertyNoThrow(Handle<JSObject> object, |
| 300 Handle<String> key, | 331 Handle<String> key, |
| 301 Handle<Object> value, | 332 Handle<Object> value, |
| 302 PropertyAttributes attributes) { | 333 PropertyAttributes attributes) { |
| 303 ASSERT(!Top::has_pending_exception()); | 334 ASSERT(!object->GetIsolate()->has_pending_exception()); |
| 304 CHECK(!SetLocalPropertyIgnoreAttributes( | 335 CHECK(!SetLocalPropertyIgnoreAttributes( |
| 305 object, key, value, attributes).is_null()); | 336 object, key, value, attributes).is_null()); |
| 306 CHECK(!Top::has_pending_exception()); | 337 CHECK(!object->GetIsolate()->has_pending_exception()); |
| 307 } | 338 } |
| 308 | 339 |
| 309 | 340 |
| 310 Handle<Object> SetPropertyWithInterceptor(Handle<JSObject> object, | 341 Handle<Object> SetPropertyWithInterceptor(Handle<JSObject> object, |
| 311 Handle<String> key, | 342 Handle<String> key, |
| 312 Handle<Object> value, | 343 Handle<Object> value, |
| 313 PropertyAttributes attributes, | 344 PropertyAttributes attributes, |
| 314 StrictModeFlag strict_mode) { | 345 StrictModeFlag strict_mode) { |
| 315 CALL_HEAP_FUNCTION(object->SetPropertyWithInterceptor(*key, | 346 CALL_HEAP_FUNCTION(object->GetIsolate(), |
| 347 object->SetPropertyWithInterceptor(*key, |
| 316 *value, | 348 *value, |
| 317 attributes, | 349 attributes, |
| 318 strict_mode), | 350 strict_mode), |
| 319 Object); | 351 Object); |
| 320 } | 352 } |
| 321 | 353 |
| 322 | 354 |
| 323 Handle<Object> GetProperty(Handle<JSObject> obj, | 355 Handle<Object> GetProperty(Handle<JSObject> obj, |
| 324 const char* name) { | 356 const char* name) { |
| 325 Handle<String> str = Factory::LookupAsciiSymbol(name); | 357 Isolate* isolate = obj->GetIsolate(); |
| 326 CALL_HEAP_FUNCTION(obj->GetProperty(*str), Object); | 358 Handle<String> str = isolate->factory()->LookupAsciiSymbol(name); |
| 359 CALL_HEAP_FUNCTION(isolate, obj->GetProperty(*str), Object); |
| 327 } | 360 } |
| 328 | 361 |
| 329 | 362 |
| 330 Handle<Object> GetProperty(Handle<Object> obj, | 363 Handle<Object> GetProperty(Handle<Object> obj, |
| 331 Handle<Object> key) { | 364 Handle<Object> key) { |
| 332 CALL_HEAP_FUNCTION(Runtime::GetObjectProperty(obj, key), Object); | 365 Isolate* isolate = Isolate::Current(); |
| 366 CALL_HEAP_FUNCTION(isolate, |
| 367 Runtime::GetObjectProperty(isolate, obj, key), Object); |
| 333 } | 368 } |
| 334 | 369 |
| 335 | 370 |
| 336 Handle<Object> GetElement(Handle<Object> obj, | 371 Handle<Object> GetElement(Handle<Object> obj, |
| 337 uint32_t index) { | 372 uint32_t index) { |
| 338 CALL_HEAP_FUNCTION(Runtime::GetElement(obj, index), Object); | 373 Isolate* isolate = Isolate::Current(); |
| 374 CALL_HEAP_FUNCTION(isolate, Runtime::GetElement(obj, index), Object); |
| 339 } | 375 } |
| 340 | 376 |
| 341 | 377 |
| 342 Handle<Object> GetPropertyWithInterceptor(Handle<JSObject> receiver, | 378 Handle<Object> GetPropertyWithInterceptor(Handle<JSObject> receiver, |
| 343 Handle<JSObject> holder, | 379 Handle<JSObject> holder, |
| 344 Handle<String> name, | 380 Handle<String> name, |
| 345 PropertyAttributes* attributes) { | 381 PropertyAttributes* attributes) { |
| 346 CALL_HEAP_FUNCTION(holder->GetPropertyWithInterceptor(*receiver, | 382 Isolate* isolate = receiver->GetIsolate(); |
| 383 CALL_HEAP_FUNCTION(isolate, |
| 384 holder->GetPropertyWithInterceptor(*receiver, |
| 347 *name, | 385 *name, |
| 348 attributes), | 386 attributes), |
| 349 Object); | 387 Object); |
| 350 } | 388 } |
| 351 | 389 |
| 352 | 390 |
| 353 Handle<Object> GetPrototype(Handle<Object> obj) { | 391 Handle<Object> GetPrototype(Handle<Object> obj) { |
| 354 Handle<Object> result(obj->GetPrototype()); | 392 Handle<Object> result(obj->GetPrototype()); |
| 355 return result; | 393 return result; |
| 356 } | 394 } |
| 357 | 395 |
| 358 | 396 |
| 359 Handle<Object> SetPrototype(Handle<JSObject> obj, Handle<Object> value) { | 397 Handle<Object> SetPrototype(Handle<JSObject> obj, Handle<Object> value) { |
| 360 const bool skip_hidden_prototypes = false; | 398 const bool skip_hidden_prototypes = false; |
| 361 CALL_HEAP_FUNCTION(obj->SetPrototype(*value, skip_hidden_prototypes), Object); | 399 CALL_HEAP_FUNCTION(obj->GetIsolate(), |
| 400 obj->SetPrototype(*value, skip_hidden_prototypes), Object); |
| 362 } | 401 } |
| 363 | 402 |
| 364 | 403 |
| 365 Handle<Object> PreventExtensions(Handle<JSObject> object) { | 404 Handle<Object> PreventExtensions(Handle<JSObject> object) { |
| 366 CALL_HEAP_FUNCTION(object->PreventExtensions(), Object); | 405 CALL_HEAP_FUNCTION(object->GetIsolate(), object->PreventExtensions(), Object); |
| 367 } | 406 } |
| 368 | 407 |
| 369 | 408 |
| 370 Handle<Object> GetHiddenProperties(Handle<JSObject> obj, | 409 Handle<Object> GetHiddenProperties(Handle<JSObject> obj, |
| 371 bool create_if_needed) { | 410 bool create_if_needed) { |
| 411 Isolate* isolate = obj->GetIsolate(); |
| 372 Object* holder = obj->BypassGlobalProxy(); | 412 Object* holder = obj->BypassGlobalProxy(); |
| 373 if (holder->IsUndefined()) return Factory::undefined_value(); | 413 if (holder->IsUndefined()) return isolate->factory()->undefined_value(); |
| 374 obj = Handle<JSObject>(JSObject::cast(holder)); | 414 obj = Handle<JSObject>(JSObject::cast(holder)); |
| 375 | 415 |
| 376 if (obj->HasFastProperties()) { | 416 if (obj->HasFastProperties()) { |
| 377 // If the object has fast properties, check whether the first slot | 417 // If the object has fast properties, check whether the first slot |
| 378 // in the descriptor array matches the hidden symbol. Since the | 418 // in the descriptor array matches the hidden symbol. Since the |
| 379 // hidden symbols hash code is zero (and no other string has hash | 419 // hidden symbols hash code is zero (and no other string has hash |
| 380 // code zero) it will always occupy the first entry if present. | 420 // code zero) it will always occupy the first entry if present. |
| 381 DescriptorArray* descriptors = obj->map()->instance_descriptors(); | 421 DescriptorArray* descriptors = obj->map()->instance_descriptors(); |
| 382 if ((descriptors->number_of_descriptors() > 0) && | 422 if ((descriptors->number_of_descriptors() > 0) && |
| 383 (descriptors->GetKey(0) == Heap::hidden_symbol()) && | 423 (descriptors->GetKey(0) == isolate->heap()->hidden_symbol()) && |
| 384 descriptors->IsProperty(0)) { | 424 descriptors->IsProperty(0)) { |
| 385 ASSERT(descriptors->GetType(0) == FIELD); | 425 ASSERT(descriptors->GetType(0) == FIELD); |
| 386 return Handle<Object>(obj->FastPropertyAt(descriptors->GetFieldIndex(0))); | 426 return Handle<Object>(obj->FastPropertyAt(descriptors->GetFieldIndex(0))); |
| 387 } | 427 } |
| 388 } | 428 } |
| 389 | 429 |
| 390 // Only attempt to find the hidden properties in the local object and not | 430 // Only attempt to find the hidden properties in the local object and not |
| 391 // in the prototype chain. Note that HasLocalProperty() can cause a GC in | 431 // in the prototype chain. Note that HasLocalProperty() can cause a GC in |
| 392 // the general case in the presence of interceptors. | 432 // the general case in the presence of interceptors. |
| 393 if (!obj->HasHiddenPropertiesObject()) { | 433 if (!obj->HasHiddenPropertiesObject()) { |
| 394 // Hidden properties object not found. Allocate a new hidden properties | 434 // Hidden properties object not found. Allocate a new hidden properties |
| 395 // object if requested. Otherwise return the undefined value. | 435 // object if requested. Otherwise return the undefined value. |
| 396 if (create_if_needed) { | 436 if (create_if_needed) { |
| 397 Handle<Object> hidden_obj = Factory::NewJSObject(Top::object_function()); | 437 Handle<Object> hidden_obj = |
| 398 CALL_HEAP_FUNCTION(obj->SetHiddenPropertiesObject(*hidden_obj), Object); | 438 isolate->factory()->NewJSObject(isolate->object_function()); |
| 439 CALL_HEAP_FUNCTION(isolate, |
| 440 obj->SetHiddenPropertiesObject(*hidden_obj), Object); |
| 399 } else { | 441 } else { |
| 400 return Factory::undefined_value(); | 442 return isolate->factory()->undefined_value(); |
| 401 } | 443 } |
| 402 } | 444 } |
| 403 return Handle<Object>(obj->GetHiddenPropertiesObject()); | 445 return Handle<Object>(obj->GetHiddenPropertiesObject(), isolate); |
| 404 } | 446 } |
| 405 | 447 |
| 406 | 448 |
| 407 Handle<Object> DeleteElement(Handle<JSObject> obj, | 449 Handle<Object> DeleteElement(Handle<JSObject> obj, |
| 408 uint32_t index) { | 450 uint32_t index) { |
| 409 CALL_HEAP_FUNCTION(obj->DeleteElement(index, JSObject::NORMAL_DELETION), | 451 CALL_HEAP_FUNCTION(obj->GetIsolate(), |
| 452 obj->DeleteElement(index, JSObject::NORMAL_DELETION), |
| 410 Object); | 453 Object); |
| 411 } | 454 } |
| 412 | 455 |
| 413 | 456 |
| 414 Handle<Object> DeleteProperty(Handle<JSObject> obj, | 457 Handle<Object> DeleteProperty(Handle<JSObject> obj, |
| 415 Handle<String> prop) { | 458 Handle<String> prop) { |
| 416 CALL_HEAP_FUNCTION(obj->DeleteProperty(*prop, JSObject::NORMAL_DELETION), | 459 CALL_HEAP_FUNCTION(obj->GetIsolate(), |
| 460 obj->DeleteProperty(*prop, JSObject::NORMAL_DELETION), |
| 417 Object); | 461 Object); |
| 418 } | 462 } |
| 419 | 463 |
| 420 | 464 |
| 421 Handle<Object> LookupSingleCharacterStringFromCode(uint32_t index) { | 465 Handle<Object> LookupSingleCharacterStringFromCode(uint32_t index) { |
| 422 CALL_HEAP_FUNCTION(Heap::LookupSingleCharacterStringFromCode(index), Object); | 466 Isolate* isolate = Isolate::Current(); |
| 467 CALL_HEAP_FUNCTION( |
| 468 isolate, |
| 469 isolate->heap()->LookupSingleCharacterStringFromCode(index), Object); |
| 423 } | 470 } |
| 424 | 471 |
| 425 | 472 |
| 426 Handle<String> SubString(Handle<String> str, | 473 Handle<String> SubString(Handle<String> str, |
| 427 int start, | 474 int start, |
| 428 int end, | 475 int end, |
| 429 PretenureFlag pretenure) { | 476 PretenureFlag pretenure) { |
| 430 CALL_HEAP_FUNCTION(str->SubString(start, end, pretenure), String); | 477 CALL_HEAP_FUNCTION(str->GetIsolate(), |
| 478 str->SubString(start, end, pretenure), String); |
| 431 } | 479 } |
| 432 | 480 |
| 433 | 481 |
| 434 Handle<Object> SetElement(Handle<JSObject> object, | 482 Handle<Object> SetElement(Handle<JSObject> object, |
| 435 uint32_t index, | 483 uint32_t index, |
| 436 Handle<Object> value, | 484 Handle<Object> value, |
| 437 StrictModeFlag strict_mode) { | 485 StrictModeFlag strict_mode) { |
| 438 if (object->HasExternalArrayElements()) { | 486 if (object->HasExternalArrayElements()) { |
| 439 if (!value->IsSmi() && !value->IsHeapNumber() && !value->IsUndefined()) { | 487 if (!value->IsSmi() && !value->IsHeapNumber() && !value->IsUndefined()) { |
| 440 bool has_exception; | 488 bool has_exception; |
| 441 Handle<Object> number = Execution::ToNumber(value, &has_exception); | 489 Handle<Object> number = Execution::ToNumber(value, &has_exception); |
| 442 if (has_exception) return Handle<Object>(); | 490 if (has_exception) return Handle<Object>(); |
| 443 value = number; | 491 value = number; |
| 444 } | 492 } |
| 445 } | 493 } |
| 446 CALL_HEAP_FUNCTION(object->SetElement(index, *value, strict_mode), Object); | 494 CALL_HEAP_FUNCTION(object->GetIsolate(), |
| 495 object->SetElement(index, *value, strict_mode), Object); |
| 447 } | 496 } |
| 448 | 497 |
| 449 | 498 |
| 450 Handle<Object> SetOwnElement(Handle<JSObject> object, | 499 Handle<Object> SetOwnElement(Handle<JSObject> object, |
| 451 uint32_t index, | 500 uint32_t index, |
| 452 Handle<Object> value, | 501 Handle<Object> value, |
| 453 StrictModeFlag strict_mode) { | 502 StrictModeFlag strict_mode) { |
| 454 ASSERT(!object->HasExternalArrayElements()); | 503 ASSERT(!object->HasExternalArrayElements()); |
| 455 CALL_HEAP_FUNCTION(object->SetElement(index, *value, strict_mode, false), | 504 CALL_HEAP_FUNCTION(object->GetIsolate(), |
| 505 object->SetElement(index, *value, strict_mode, false), |
| 456 Object); | 506 Object); |
| 457 } | 507 } |
| 458 | 508 |
| 459 | 509 |
| 460 Handle<JSObject> Copy(Handle<JSObject> obj) { | 510 Handle<JSObject> Copy(Handle<JSObject> obj) { |
| 461 CALL_HEAP_FUNCTION(Heap::CopyJSObject(*obj), JSObject); | 511 Isolate* isolate = obj->GetIsolate(); |
| 512 CALL_HEAP_FUNCTION(isolate, |
| 513 isolate->heap()->CopyJSObject(*obj), JSObject); |
| 462 } | 514 } |
| 463 | 515 |
| 464 | 516 |
| 465 Handle<Object> SetAccessor(Handle<JSObject> obj, Handle<AccessorInfo> info) { | 517 Handle<Object> SetAccessor(Handle<JSObject> obj, Handle<AccessorInfo> info) { |
| 466 CALL_HEAP_FUNCTION(obj->DefineAccessor(*info), Object); | 518 CALL_HEAP_FUNCTION(obj->GetIsolate(), obj->DefineAccessor(*info), Object); |
| 467 } | 519 } |
| 468 | 520 |
| 469 | 521 |
| 470 // Wrappers for scripts are kept alive and cached in weak global | 522 // Wrappers for scripts are kept alive and cached in weak global |
| 471 // handles referred from proxy objects held by the scripts as long as | 523 // handles referred from proxy objects held by the scripts as long as |
| 472 // they are used. When they are not used anymore, the garbage | 524 // they are used. When they are not used anymore, the garbage |
| 473 // collector will call the weak callback on the global handle | 525 // collector will call the weak callback on the global handle |
| 474 // associated with the wrapper and get rid of both the wrapper and the | 526 // associated with the wrapper and get rid of both the wrapper and the |
| 475 // handle. | 527 // handle. |
| 476 static void ClearWrapperCache(Persistent<v8::Value> handle, void*) { | 528 static void ClearWrapperCache(Persistent<v8::Value> handle, void*) { |
| 477 #ifdef ENABLE_HEAP_PROTECTION | 529 #ifdef ENABLE_HEAP_PROTECTION |
| 478 // Weak reference callbacks are called as if from outside V8. We | 530 // Weak reference callbacks are called as if from outside V8. We |
| 479 // need to reeenter to unprotect the heap. | 531 // need to reeenter to unprotect the heap. |
| 480 VMState state(OTHER); | 532 VMState state(OTHER); |
| 481 #endif | 533 #endif |
| 482 Handle<Object> cache = Utils::OpenHandle(*handle); | 534 Handle<Object> cache = Utils::OpenHandle(*handle); |
| 483 JSValue* wrapper = JSValue::cast(*cache); | 535 JSValue* wrapper = JSValue::cast(*cache); |
| 484 Proxy* proxy = Script::cast(wrapper->value())->wrapper(); | 536 Proxy* proxy = Script::cast(wrapper->value())->wrapper(); |
| 485 ASSERT(proxy->proxy() == reinterpret_cast<Address>(cache.location())); | 537 ASSERT(proxy->proxy() == reinterpret_cast<Address>(cache.location())); |
| 486 proxy->set_proxy(0); | 538 proxy->set_proxy(0); |
| 487 GlobalHandles::Destroy(cache.location()); | 539 Isolate::Current()->global_handles()->Destroy(cache.location()); |
| 488 Counters::script_wrappers.Decrement(); | 540 COUNTERS->script_wrappers()->Decrement(); |
| 489 } | 541 } |
| 490 | 542 |
| 491 | 543 |
| 492 Handle<JSValue> GetScriptWrapper(Handle<Script> script) { | 544 Handle<JSValue> GetScriptWrapper(Handle<Script> script) { |
| 545 Isolate* isolate = Isolate::Current(); |
| 493 if (script->wrapper()->proxy() != NULL) { | 546 if (script->wrapper()->proxy() != NULL) { |
| 494 // Return the script wrapper directly from the cache. | 547 // Return the script wrapper directly from the cache. |
| 495 return Handle<JSValue>( | 548 return Handle<JSValue>( |
| 496 reinterpret_cast<JSValue**>(script->wrapper()->proxy())); | 549 reinterpret_cast<JSValue**>(script->wrapper()->proxy())); |
| 497 } | 550 } |
| 498 | 551 |
| 499 // Construct a new script wrapper. | 552 // Construct a new script wrapper. |
| 500 Counters::script_wrappers.Increment(); | 553 isolate->counters()->script_wrappers()->Increment(); |
| 501 Handle<JSFunction> constructor = Top::script_function(); | 554 Handle<JSFunction> constructor = isolate->script_function(); |
| 502 Handle<JSValue> result = | 555 Handle<JSValue> result = |
| 503 Handle<JSValue>::cast(Factory::NewJSObject(constructor)); | 556 Handle<JSValue>::cast(isolate->factory()->NewJSObject(constructor)); |
| 504 result->set_value(*script); | 557 result->set_value(*script); |
| 505 | 558 |
| 506 // Create a new weak global handle and use it to cache the wrapper | 559 // Create a new weak global handle and use it to cache the wrapper |
| 507 // for future use. The cache will automatically be cleared by the | 560 // for future use. The cache will automatically be cleared by the |
| 508 // garbage collector when it is not used anymore. | 561 // garbage collector when it is not used anymore. |
| 509 Handle<Object> handle = GlobalHandles::Create(*result); | 562 Handle<Object> handle = isolate->global_handles()->Create(*result); |
| 510 GlobalHandles::MakeWeak(handle.location(), NULL, &ClearWrapperCache); | 563 isolate->global_handles()->MakeWeak(handle.location(), NULL, |
| 564 &ClearWrapperCache); |
| 511 script->wrapper()->set_proxy(reinterpret_cast<Address>(handle.location())); | 565 script->wrapper()->set_proxy(reinterpret_cast<Address>(handle.location())); |
| 512 return result; | 566 return result; |
| 513 } | 567 } |
| 514 | 568 |
| 515 | 569 |
| 516 // Init line_ends array with code positions of line ends inside script | 570 // Init line_ends array with code positions of line ends inside script |
| 517 // source. | 571 // source. |
| 518 void InitScriptLineEnds(Handle<Script> script) { | 572 void InitScriptLineEnds(Handle<Script> script) { |
| 519 if (!script->line_ends()->IsUndefined()) return; | 573 if (!script->line_ends()->IsUndefined()) return; |
| 520 | 574 |
| 521 if (!script->source()->IsString()) { | 575 if (!script->source()->IsString()) { |
| 522 ASSERT(script->source()->IsUndefined()); | 576 ASSERT(script->source()->IsUndefined()); |
| 523 Handle<FixedArray> empty = Factory::NewFixedArray(0); | 577 Handle<FixedArray> empty = |
| 578 script->GetIsolate()->factory()->NewFixedArray(0); |
| 524 script->set_line_ends(*empty); | 579 script->set_line_ends(*empty); |
| 525 ASSERT(script->line_ends()->IsFixedArray()); | 580 ASSERT(script->line_ends()->IsFixedArray()); |
| 526 return; | 581 return; |
| 527 } | 582 } |
| 528 | 583 |
| 529 Handle<String> src(String::cast(script->source())); | 584 Handle<String> src(String::cast(script->source())); |
| 530 | 585 |
| 531 Handle<FixedArray> array = CalculateLineEnds(src, true); | 586 Handle<FixedArray> array = CalculateLineEnds(src, true); |
| 532 | 587 |
| 533 if (*array != Heap::empty_fixed_array()) { | 588 if (*array != HEAP->empty_fixed_array()) { |
| 534 array->set_map(Heap::fixed_cow_array_map()); | 589 array->set_map(HEAP->fixed_cow_array_map()); |
| 535 } | 590 } |
| 536 | 591 |
| 537 script->set_line_ends(*array); | 592 script->set_line_ends(*array); |
| 538 ASSERT(script->line_ends()->IsFixedArray()); | 593 ASSERT(script->line_ends()->IsFixedArray()); |
| 539 } | 594 } |
| 540 | 595 |
| 541 | 596 |
| 542 template <typename SourceChar> | 597 template <typename SourceChar> |
| 543 static void CalculateLineEnds(List<int>* line_ends, | 598 static void CalculateLineEnds(Isolate* isolate, |
| 599 List<int>* line_ends, |
| 544 Vector<const SourceChar> src, | 600 Vector<const SourceChar> src, |
| 545 bool with_last_line) { | 601 bool with_last_line) { |
| 546 const int src_len = src.length(); | 602 const int src_len = src.length(); |
| 547 StringSearch<char, SourceChar> search(CStrVector("\n")); | 603 StringSearch<char, SourceChar> search(isolate, CStrVector("\n")); |
| 548 | 604 |
| 549 // Find and record line ends. | 605 // Find and record line ends. |
| 550 int position = 0; | 606 int position = 0; |
| 551 while (position != -1 && position < src_len) { | 607 while (position != -1 && position < src_len) { |
| 552 position = search.Search(src, position); | 608 position = search.Search(src, position); |
| 553 if (position != -1) { | 609 if (position != -1) { |
| 554 line_ends->Add(position); | 610 line_ends->Add(position); |
| 555 position++; | 611 position++; |
| 556 } else if (with_last_line) { | 612 } else if (with_last_line) { |
| 557 // Even if the last line misses a line end, it is counted. | 613 // Even if the last line misses a line end, it is counted. |
| 558 line_ends->Add(src_len); | 614 line_ends->Add(src_len); |
| 559 return; | 615 return; |
| 560 } | 616 } |
| 561 } | 617 } |
| 562 } | 618 } |
| 563 | 619 |
| 564 | 620 |
| 565 Handle<FixedArray> CalculateLineEnds(Handle<String> src, | 621 Handle<FixedArray> CalculateLineEnds(Handle<String> src, |
| 566 bool with_last_line) { | 622 bool with_last_line) { |
| 567 src = FlattenGetString(src); | 623 src = FlattenGetString(src); |
| 568 // Rough estimate of line count based on a roughly estimated average | 624 // Rough estimate of line count based on a roughly estimated average |
| 569 // length of (unpacked) code. | 625 // length of (unpacked) code. |
| 570 int line_count_estimate = src->length() >> 4; | 626 int line_count_estimate = src->length() >> 4; |
| 571 List<int> line_ends(line_count_estimate); | 627 List<int> line_ends(line_count_estimate); |
| 572 { | 628 { |
| 573 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid. | 629 AssertNoAllocation no_heap_allocation; // ensure vectors stay valid. |
| 630 Isolate* isolate = src->GetIsolate(); |
| 574 // Dispatch on type of strings. | 631 // Dispatch on type of strings. |
| 575 if (src->IsAsciiRepresentation()) { | 632 if (src->IsAsciiRepresentation()) { |
| 576 CalculateLineEnds(&line_ends, src->ToAsciiVector(), with_last_line); | 633 CalculateLineEnds(isolate, |
| 634 &line_ends, |
| 635 src->ToAsciiVector(), |
| 636 with_last_line); |
| 577 } else { | 637 } else { |
| 578 CalculateLineEnds(&line_ends, src->ToUC16Vector(), with_last_line); | 638 CalculateLineEnds(isolate, |
| 639 &line_ends, |
| 640 src->ToUC16Vector(), |
| 641 with_last_line); |
| 579 } | 642 } |
| 580 } | 643 } |
| 581 int line_count = line_ends.length(); | 644 int line_count = line_ends.length(); |
| 582 Handle<FixedArray> array = Factory::NewFixedArray(line_count); | 645 Handle<FixedArray> array = FACTORY->NewFixedArray(line_count); |
| 583 for (int i = 0; i < line_count; i++) { | 646 for (int i = 0; i < line_count; i++) { |
| 584 array->set(i, Smi::FromInt(line_ends[i])); | 647 array->set(i, Smi::FromInt(line_ends[i])); |
| 585 } | 648 } |
| 586 return array; | 649 return array; |
| 587 } | 650 } |
| 588 | 651 |
| 589 | 652 |
| 590 // Convert code position into line number. | 653 // Convert code position into line number. |
| 591 int GetScriptLineNumber(Handle<Script> script, int code_pos) { | 654 int GetScriptLineNumber(Handle<Script> script, int code_pos) { |
| 592 InitScriptLineEnds(script); | 655 InitScriptLineEnds(script); |
| (...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 638 | 701 |
| 639 | 702 |
| 640 void CustomArguments::IterateInstance(ObjectVisitor* v) { | 703 void CustomArguments::IterateInstance(ObjectVisitor* v) { |
| 641 v->VisitPointers(values_, values_ + ARRAY_SIZE(values_)); | 704 v->VisitPointers(values_, values_ + ARRAY_SIZE(values_)); |
| 642 } | 705 } |
| 643 | 706 |
| 644 | 707 |
| 645 // Compute the property keys from the interceptor. | 708 // Compute the property keys from the interceptor. |
| 646 v8::Handle<v8::Array> GetKeysForNamedInterceptor(Handle<JSObject> receiver, | 709 v8::Handle<v8::Array> GetKeysForNamedInterceptor(Handle<JSObject> receiver, |
| 647 Handle<JSObject> object) { | 710 Handle<JSObject> object) { |
| 711 Isolate* isolate = receiver->GetIsolate(); |
| 648 Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor()); | 712 Handle<InterceptorInfo> interceptor(object->GetNamedInterceptor()); |
| 649 CustomArguments args(interceptor->data(), *receiver, *object); | 713 CustomArguments args(isolate, interceptor->data(), *receiver, *object); |
| 650 v8::AccessorInfo info(args.end()); | 714 v8::AccessorInfo info(args.end()); |
| 651 v8::Handle<v8::Array> result; | 715 v8::Handle<v8::Array> result; |
| 652 if (!interceptor->enumerator()->IsUndefined()) { | 716 if (!interceptor->enumerator()->IsUndefined()) { |
| 653 v8::NamedPropertyEnumerator enum_fun = | 717 v8::NamedPropertyEnumerator enum_fun = |
| 654 v8::ToCData<v8::NamedPropertyEnumerator>(interceptor->enumerator()); | 718 v8::ToCData<v8::NamedPropertyEnumerator>(interceptor->enumerator()); |
| 655 LOG(ApiObjectAccess("interceptor-named-enum", *object)); | 719 LOG(isolate, ApiObjectAccess("interceptor-named-enum", *object)); |
| 656 { | 720 { |
| 657 // Leaving JavaScript. | 721 // Leaving JavaScript. |
| 658 VMState state(EXTERNAL); | 722 VMState state(isolate, EXTERNAL); |
| 659 result = enum_fun(info); | 723 result = enum_fun(info); |
| 660 } | 724 } |
| 661 } | 725 } |
| 662 return result; | 726 return result; |
| 663 } | 727 } |
| 664 | 728 |
| 665 | 729 |
| 666 // Compute the element keys from the interceptor. | 730 // Compute the element keys from the interceptor. |
| 667 v8::Handle<v8::Array> GetKeysForIndexedInterceptor(Handle<JSObject> receiver, | 731 v8::Handle<v8::Array> GetKeysForIndexedInterceptor(Handle<JSObject> receiver, |
| 668 Handle<JSObject> object) { | 732 Handle<JSObject> object) { |
| 733 Isolate* isolate = receiver->GetIsolate(); |
| 669 Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor()); | 734 Handle<InterceptorInfo> interceptor(object->GetIndexedInterceptor()); |
| 670 CustomArguments args(interceptor->data(), *receiver, *object); | 735 CustomArguments args(isolate, interceptor->data(), *receiver, *object); |
| 671 v8::AccessorInfo info(args.end()); | 736 v8::AccessorInfo info(args.end()); |
| 672 v8::Handle<v8::Array> result; | 737 v8::Handle<v8::Array> result; |
| 673 if (!interceptor->enumerator()->IsUndefined()) { | 738 if (!interceptor->enumerator()->IsUndefined()) { |
| 674 v8::IndexedPropertyEnumerator enum_fun = | 739 v8::IndexedPropertyEnumerator enum_fun = |
| 675 v8::ToCData<v8::IndexedPropertyEnumerator>(interceptor->enumerator()); | 740 v8::ToCData<v8::IndexedPropertyEnumerator>(interceptor->enumerator()); |
| 676 LOG(ApiObjectAccess("interceptor-indexed-enum", *object)); | 741 LOG(isolate, ApiObjectAccess("interceptor-indexed-enum", *object)); |
| 677 { | 742 { |
| 678 // Leaving JavaScript. | 743 // Leaving JavaScript. |
| 679 VMState state(EXTERNAL); | 744 VMState state(isolate, EXTERNAL); |
| 680 result = enum_fun(info); | 745 result = enum_fun(info); |
| 681 } | 746 } |
| 682 } | 747 } |
| 683 return result; | 748 return result; |
| 684 } | 749 } |
| 685 | 750 |
| 686 | 751 |
| 687 static bool ContainsOnlyValidKeys(Handle<FixedArray> array) { | 752 static bool ContainsOnlyValidKeys(Handle<FixedArray> array) { |
| 688 int len = array->length(); | 753 int len = array->length(); |
| 689 for (int i = 0; i < len; i++) { | 754 for (int i = 0; i < len; i++) { |
| 690 Object* e = array->get(i); | 755 Object* e = array->get(i); |
| 691 if (!(e->IsString() || e->IsNumber())) return false; | 756 if (!(e->IsString() || e->IsNumber())) return false; |
| 692 } | 757 } |
| 693 return true; | 758 return true; |
| 694 } | 759 } |
| 695 | 760 |
| 696 | 761 |
| 697 Handle<FixedArray> GetKeysInFixedArrayFor(Handle<JSObject> object, | 762 Handle<FixedArray> GetKeysInFixedArrayFor(Handle<JSObject> object, |
| 698 KeyCollectionType type) { | 763 KeyCollectionType type) { |
| 699 USE(ContainsOnlyValidKeys); | 764 USE(ContainsOnlyValidKeys); |
| 700 Handle<FixedArray> content = Factory::empty_fixed_array(); | 765 Isolate* isolate = object->GetIsolate(); |
| 766 Handle<FixedArray> content = isolate->factory()->empty_fixed_array(); |
| 701 Handle<JSObject> arguments_boilerplate = | 767 Handle<JSObject> arguments_boilerplate = |
| 702 Handle<JSObject>( | 768 Handle<JSObject>( |
| 703 Top::context()->global_context()->arguments_boilerplate()); | 769 isolate->context()->global_context()->arguments_boilerplate()); |
| 704 Handle<JSFunction> arguments_function = | 770 Handle<JSFunction> arguments_function = |
| 705 Handle<JSFunction>( | 771 Handle<JSFunction>( |
| 706 JSFunction::cast(arguments_boilerplate->map()->constructor())); | 772 JSFunction::cast(arguments_boilerplate->map()->constructor())); |
| 707 | 773 |
| 708 // Only collect keys if access is permitted. | 774 // Only collect keys if access is permitted. |
| 709 for (Handle<Object> p = object; | 775 for (Handle<Object> p = object; |
| 710 *p != Heap::null_value(); | 776 *p != isolate->heap()->null_value(); |
| 711 p = Handle<Object>(p->GetPrototype())) { | 777 p = Handle<Object>(p->GetPrototype())) { |
| 712 Handle<JSObject> current(JSObject::cast(*p)); | 778 Handle<JSObject> current(JSObject::cast(*p)); |
| 713 | 779 |
| 714 // Check access rights if required. | 780 // Check access rights if required. |
| 715 if (current->IsAccessCheckNeeded() && | 781 if (current->IsAccessCheckNeeded() && |
| 716 !Top::MayNamedAccess(*current, Heap::undefined_value(), | 782 !isolate->MayNamedAccess(*current, |
| 717 v8::ACCESS_KEYS)) { | 783 isolate->heap()->undefined_value(), |
| 718 Top::ReportFailedAccessCheck(*current, v8::ACCESS_KEYS); | 784 v8::ACCESS_KEYS)) { |
| 785 isolate->ReportFailedAccessCheck(*current, v8::ACCESS_KEYS); |
| 719 break; | 786 break; |
| 720 } | 787 } |
| 721 | 788 |
| 722 // Compute the element keys. | 789 // Compute the element keys. |
| 723 Handle<FixedArray> element_keys = | 790 Handle<FixedArray> element_keys = |
| 724 Factory::NewFixedArray(current->NumberOfEnumElements()); | 791 isolate->factory()->NewFixedArray(current->NumberOfEnumElements()); |
| 725 current->GetEnumElementKeys(*element_keys); | 792 current->GetEnumElementKeys(*element_keys); |
| 726 content = UnionOfKeys(content, element_keys); | 793 content = UnionOfKeys(content, element_keys); |
| 727 ASSERT(ContainsOnlyValidKeys(content)); | 794 ASSERT(ContainsOnlyValidKeys(content)); |
| 728 | 795 |
| 729 // Add the element keys from the interceptor. | 796 // Add the element keys from the interceptor. |
| 730 if (current->HasIndexedInterceptor()) { | 797 if (current->HasIndexedInterceptor()) { |
| 731 v8::Handle<v8::Array> result = | 798 v8::Handle<v8::Array> result = |
| 732 GetKeysForIndexedInterceptor(object, current); | 799 GetKeysForIndexedInterceptor(object, current); |
| 733 if (!result.IsEmpty()) | 800 if (!result.IsEmpty()) |
| 734 content = AddKeysFromJSArray(content, v8::Utils::OpenHandle(*result)); | 801 content = AddKeysFromJSArray(content, v8::Utils::OpenHandle(*result)); |
| (...skipping 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 768 // If we only want local properties we bail out after the first | 835 // If we only want local properties we bail out after the first |
| 769 // iteration. | 836 // iteration. |
| 770 if (type == LOCAL_ONLY) | 837 if (type == LOCAL_ONLY) |
| 771 break; | 838 break; |
| 772 } | 839 } |
| 773 return content; | 840 return content; |
| 774 } | 841 } |
| 775 | 842 |
| 776 | 843 |
| 777 Handle<JSArray> GetKeysFor(Handle<JSObject> object) { | 844 Handle<JSArray> GetKeysFor(Handle<JSObject> object) { |
| 778 Counters::for_in.Increment(); | 845 Isolate* isolate = object->GetIsolate(); |
| 846 isolate->counters()->for_in()->Increment(); |
| 779 Handle<FixedArray> elements = GetKeysInFixedArrayFor(object, | 847 Handle<FixedArray> elements = GetKeysInFixedArrayFor(object, |
| 780 INCLUDE_PROTOS); | 848 INCLUDE_PROTOS); |
| 781 return Factory::NewJSArrayWithElements(elements); | 849 return isolate->factory()->NewJSArrayWithElements(elements); |
| 782 } | 850 } |
| 783 | 851 |
| 784 | 852 |
| 785 Handle<FixedArray> GetEnumPropertyKeys(Handle<JSObject> object, | 853 Handle<FixedArray> GetEnumPropertyKeys(Handle<JSObject> object, |
| 786 bool cache_result) { | 854 bool cache_result) { |
| 787 int index = 0; | 855 int index = 0; |
| 856 Isolate* isolate = object->GetIsolate(); |
| 788 if (object->HasFastProperties()) { | 857 if (object->HasFastProperties()) { |
| 789 if (object->map()->instance_descriptors()->HasEnumCache()) { | 858 if (object->map()->instance_descriptors()->HasEnumCache()) { |
| 790 Counters::enum_cache_hits.Increment(); | 859 isolate->counters()->enum_cache_hits()->Increment(); |
| 791 DescriptorArray* desc = object->map()->instance_descriptors(); | 860 DescriptorArray* desc = object->map()->instance_descriptors(); |
| 792 return Handle<FixedArray>(FixedArray::cast(desc->GetEnumCache())); | 861 return Handle<FixedArray>(FixedArray::cast(desc->GetEnumCache())); |
| 793 } | 862 } |
| 794 Counters::enum_cache_misses.Increment(); | 863 isolate->counters()->enum_cache_misses()->Increment(); |
| 795 int num_enum = object->NumberOfEnumProperties(); | 864 int num_enum = object->NumberOfEnumProperties(); |
| 796 Handle<FixedArray> storage = Factory::NewFixedArray(num_enum); | 865 Handle<FixedArray> storage = isolate->factory()->NewFixedArray(num_enum); |
| 797 Handle<FixedArray> sort_array = Factory::NewFixedArray(num_enum); | 866 Handle<FixedArray> sort_array = isolate->factory()->NewFixedArray(num_enum); |
| 798 Handle<DescriptorArray> descs = | 867 Handle<DescriptorArray> descs = |
| 799 Handle<DescriptorArray>(object->map()->instance_descriptors()); | 868 Handle<DescriptorArray>(object->map()->instance_descriptors()); |
| 800 for (int i = 0; i < descs->number_of_descriptors(); i++) { | 869 for (int i = 0; i < descs->number_of_descriptors(); i++) { |
| 801 if (descs->IsProperty(i) && !descs->IsDontEnum(i)) { | 870 if (descs->IsProperty(i) && !descs->IsDontEnum(i)) { |
| 802 (*storage)->set(index, descs->GetKey(i)); | 871 (*storage)->set(index, descs->GetKey(i)); |
| 803 PropertyDetails details(descs->GetDetails(i)); | 872 PropertyDetails details(descs->GetDetails(i)); |
| 804 (*sort_array)->set(index, Smi::FromInt(details.index())); | 873 (*sort_array)->set(index, Smi::FromInt(details.index())); |
| 805 index++; | 874 index++; |
| 806 } | 875 } |
| 807 } | 876 } |
| 808 (*storage)->SortPairs(*sort_array, sort_array->length()); | 877 (*storage)->SortPairs(*sort_array, sort_array->length()); |
| 809 if (cache_result) { | 878 if (cache_result) { |
| 810 Handle<FixedArray> bridge_storage = | 879 Handle<FixedArray> bridge_storage = |
| 811 Factory::NewFixedArray(DescriptorArray::kEnumCacheBridgeLength); | 880 isolate->factory()->NewFixedArray( |
| 881 DescriptorArray::kEnumCacheBridgeLength); |
| 812 DescriptorArray* desc = object->map()->instance_descriptors(); | 882 DescriptorArray* desc = object->map()->instance_descriptors(); |
| 813 desc->SetEnumCache(*bridge_storage, *storage); | 883 desc->SetEnumCache(*bridge_storage, *storage); |
| 814 } | 884 } |
| 815 ASSERT(storage->length() == index); | 885 ASSERT(storage->length() == index); |
| 816 return storage; | 886 return storage; |
| 817 } else { | 887 } else { |
| 818 int num_enum = object->NumberOfEnumProperties(); | 888 int num_enum = object->NumberOfEnumProperties(); |
| 819 Handle<FixedArray> storage = Factory::NewFixedArray(num_enum); | 889 Handle<FixedArray> storage = isolate->factory()->NewFixedArray(num_enum); |
| 820 Handle<FixedArray> sort_array = Factory::NewFixedArray(num_enum); | 890 Handle<FixedArray> sort_array = isolate->factory()->NewFixedArray(num_enum); |
| 821 object->property_dictionary()->CopyEnumKeysTo(*storage, *sort_array); | 891 object->property_dictionary()->CopyEnumKeysTo(*storage, *sort_array); |
| 822 return storage; | 892 return storage; |
| 823 } | 893 } |
| 824 } | 894 } |
| 825 | 895 |
| 826 | 896 |
| 827 bool EnsureCompiled(Handle<SharedFunctionInfo> shared, | 897 bool EnsureCompiled(Handle<SharedFunctionInfo> shared, |
| 828 ClearExceptionFlag flag) { | 898 ClearExceptionFlag flag) { |
| 829 return shared->is_compiled() || CompileLazyShared(shared, flag); | 899 return shared->is_compiled() || CompileLazyShared(shared, flag); |
| 830 } | 900 } |
| 831 | 901 |
| 832 | 902 |
| 833 static bool CompileLazyHelper(CompilationInfo* info, | 903 static bool CompileLazyHelper(CompilationInfo* info, |
| 834 ClearExceptionFlag flag) { | 904 ClearExceptionFlag flag) { |
| 835 // Compile the source information to a code object. | 905 // Compile the source information to a code object. |
| 836 ASSERT(info->IsOptimizing() || !info->shared_info()->is_compiled()); | 906 ASSERT(info->IsOptimizing() || !info->shared_info()->is_compiled()); |
| 837 ASSERT(!Top::has_pending_exception()); | 907 ASSERT(!info->isolate()->has_pending_exception()); |
| 838 bool result = Compiler::CompileLazy(info); | 908 bool result = Compiler::CompileLazy(info); |
| 839 ASSERT(result != Top::has_pending_exception()); | 909 ASSERT(result != Isolate::Current()->has_pending_exception()); |
| 840 if (!result && flag == CLEAR_EXCEPTION) Top::clear_pending_exception(); | 910 if (!result && flag == CLEAR_EXCEPTION) { |
| 911 info->isolate()->clear_pending_exception(); |
| 912 } |
| 841 return result; | 913 return result; |
| 842 } | 914 } |
| 843 | 915 |
| 844 | 916 |
| 845 bool CompileLazyShared(Handle<SharedFunctionInfo> shared, | 917 bool CompileLazyShared(Handle<SharedFunctionInfo> shared, |
| 846 ClearExceptionFlag flag) { | 918 ClearExceptionFlag flag) { |
| 847 CompilationInfo info(shared); | 919 CompilationInfo info(shared); |
| 848 return CompileLazyHelper(&info, flag); | 920 return CompileLazyHelper(&info, flag); |
| 849 } | 921 } |
| 850 | 922 |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 910 | 982 |
| 911 OptimizedObjectForAddingMultipleProperties:: | 983 OptimizedObjectForAddingMultipleProperties:: |
| 912 ~OptimizedObjectForAddingMultipleProperties() { | 984 ~OptimizedObjectForAddingMultipleProperties() { |
| 913 // Reoptimize the object to allow fast property access. | 985 // Reoptimize the object to allow fast property access. |
| 914 if (has_been_transformed_) { | 986 if (has_been_transformed_) { |
| 915 TransformToFastProperties(object_, unused_property_fields_); | 987 TransformToFastProperties(object_, unused_property_fields_); |
| 916 } | 988 } |
| 917 } | 989 } |
| 918 | 990 |
| 919 } } // namespace v8::internal | 991 } } // namespace v8::internal |
| OLD | NEW |