| 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 26 matching lines...) Expand all Loading... |
| 37 #include "dateparser.h" | 37 #include "dateparser.h" |
| 38 #include "dateparser-inl.h" | 38 #include "dateparser-inl.h" |
| 39 #include "debug.h" | 39 #include "debug.h" |
| 40 #include "execution.h" | 40 #include "execution.h" |
| 41 #include "jsregexp.h" | 41 #include "jsregexp.h" |
| 42 #include "platform.h" | 42 #include "platform.h" |
| 43 #include "runtime.h" | 43 #include "runtime.h" |
| 44 #include "scopeinfo.h" | 44 #include "scopeinfo.h" |
| 45 #include "v8threads.h" | 45 #include "v8threads.h" |
| 46 #include "smart-pointer.h" | 46 #include "smart-pointer.h" |
| 47 #include "parser.h" |
| 47 | 48 |
| 48 namespace v8 { namespace internal { | 49 namespace v8 { namespace internal { |
| 49 | 50 |
| 50 | 51 |
| 51 #define RUNTIME_ASSERT(value) do { \ | 52 #define RUNTIME_ASSERT(value) do { \ |
| 52 if (!(value)) return IllegalOperation(); \ | 53 if (!(value)) return IllegalOperation(); \ |
| 53 } while (false) | 54 } while (false) |
| 54 | 55 |
| 55 // Cast the given object to a value of the specified type and store | 56 // Cast the given object to a value of the specified type and store |
| 56 // it in a variable with the given name. If the object is not of the | 57 // it in a variable with the given name. If the object is not of the |
| 57 // expected type call IllegalOperation and return. | 58 // expected type call IllegalOperation and return. |
| 58 #define CONVERT_CHECKED(Type, name, obj) \ | 59 #define CONVERT_CHECKED(Type, name, obj) \ |
| 59 RUNTIME_ASSERT(obj->Is##Type()); \ | 60 RUNTIME_ASSERT(obj->Is##Type()); \ |
| 60 Type* name = Type::cast(obj); | 61 Type* name = Type::cast(obj); |
| 61 | 62 |
| 62 #define CONVERT_ARG_CHECKED(Type, name, index) \ | 63 #define CONVERT_ARG_CHECKED(Type, name, index) \ |
| 63 RUNTIME_ASSERT(args[index]->Is##Type()); \ | 64 RUNTIME_ASSERT(args[index]->Is##Type()); \ |
| 64 Handle<Type> name = args.at<Type>(index); | 65 Handle<Type> name = args.at<Type>(index); |
| 65 | 66 |
| 66 // Cast the given object to a boolean and store it in a variable with | 67 // Cast the given object to a boolean and store it in a variable with |
| 67 // the given name. If the object is not a boolean call IllegalOperation | 68 // the given name. If the object is not a boolean call IllegalOperation |
| 68 // and return. | 69 // and return. |
| 69 #define CONVERT_BOOLEAN_CHECKED(name, obj) \ | 70 #define CONVERT_BOOLEAN_CHECKED(name, obj) \ |
| 70 RUNTIME_ASSERT(obj->IsBoolean()); \ | 71 RUNTIME_ASSERT(obj->IsBoolean()); \ |
| 71 bool name = (obj)->IsTrue(); | 72 bool name = (obj)->IsTrue(); |
| 72 | 73 |
| 74 // Cast the given object to a Smi and store its value in an int variable |
| 75 // with the given name. If the object is not a Smi call IllegalOperation |
| 76 // and return. |
| 77 #define CONVERT_SMI_CHECKED(name, obj) \ |
| 78 RUNTIME_ASSERT(obj->IsSmi()); \ |
| 79 int name = Smi::cast(obj)->value(); |
| 80 |
| 73 // Cast the given object to a double and store it in a variable with | 81 // Cast the given object to a double and store it in a variable with |
| 74 // the given name. If the object is not a number (as opposed to | 82 // the given name. If the object is not a number (as opposed to |
| 75 // the number not-a-number) call IllegalOperation and return. | 83 // the number not-a-number) call IllegalOperation and return. |
| 76 #define CONVERT_DOUBLE_CHECKED(name, obj) \ | 84 #define CONVERT_DOUBLE_CHECKED(name, obj) \ |
| 77 RUNTIME_ASSERT(obj->IsNumber()); \ | 85 RUNTIME_ASSERT(obj->IsNumber()); \ |
| 78 double name = (obj)->Number(); | 86 double name = (obj)->Number(); |
| 79 | 87 |
| 80 // Call the specified converter on the object *comand store the result in | 88 // Call the specified converter on the object *comand store the result in |
| 81 // a variable of the specified type with the given name. If the | 89 // a variable of the specified type with the given name. If the |
| 82 // object is not a Number call IllegalOperation and return. | 90 // object is not a Number call IllegalOperation and return. |
| 83 #define CONVERT_NUMBER_CHECKED(type, name, Type, obj) \ | 91 #define CONVERT_NUMBER_CHECKED(type, name, Type, obj) \ |
| 84 RUNTIME_ASSERT(obj->IsNumber()); \ | 92 RUNTIME_ASSERT(obj->IsNumber()); \ |
| 85 type name = NumberTo##Type(obj); | 93 type name = NumberTo##Type(obj); |
| 86 | 94 |
| 87 // Non-reentrant string buffer for efficient general use in this file. | 95 // Non-reentrant string buffer for efficient general use in this file. |
| 88 static StaticResource<StringInputBuffer> runtime_string_input_buffer; | 96 static StaticResource<StringInputBuffer> runtime_string_input_buffer; |
| 89 | 97 |
| 90 | 98 |
| 91 static Object* IllegalOperation() { | 99 static Object* IllegalOperation() { |
| 92 return Top::Throw(Heap::illegal_access_symbol()); | 100 return Top::Throw(Heap::illegal_access_symbol()); |
| 93 } | 101 } |
| 94 | 102 |
| 95 | 103 |
| 96 static Object* Runtime_CloneObjectLiteralBoilerplate(Arguments args) { | 104 static Object* DeepCopyBoilerplate(JSObject* boilerplate) { |
| 105 StackLimitCheck check; |
| 106 if (check.HasOverflowed()) return Top::StackOverflow(); |
| 107 |
| 108 Object* result = Heap::CopyJSObject(boilerplate); |
| 109 if (result->IsFailure()) return result; |
| 110 JSObject* copy = JSObject::cast(result); |
| 111 |
| 112 // Deep copy local properties. |
| 113 if (copy->HasFastProperties()) { |
| 114 FixedArray* properties = copy->properties(); |
| 115 WriteBarrierMode mode = properties->GetWriteBarrierMode(); |
| 116 for (int i = 0; i < properties->length(); i++) { |
| 117 Object* value = properties->get(i); |
| 118 if (value->IsJSObject()) { |
| 119 JSObject* jsObject = JSObject::cast(value); |
| 120 result = DeepCopyBoilerplate(jsObject); |
| 121 if (result->IsFailure()) return result; |
| 122 properties->set(i, result, mode); |
| 123 } |
| 124 } |
| 125 mode = copy->GetWriteBarrierMode(); |
| 126 for (int i = 0; i < copy->map()->inobject_properties(); i++) { |
| 127 Object* value = copy->InObjectPropertyAt(i); |
| 128 if (value->IsJSObject()) { |
| 129 JSObject* jsObject = JSObject::cast(value); |
| 130 result = DeepCopyBoilerplate(jsObject); |
| 131 if (result->IsFailure()) return result; |
| 132 copy->InObjectPropertyAtPut(i, result, mode); |
| 133 } |
| 134 } |
| 135 } else { |
| 136 result = Heap::AllocateFixedArray(copy->NumberOfLocalProperties(NONE)); |
| 137 if (result->IsFailure()) return result; |
| 138 FixedArray* names = FixedArray::cast(result); |
| 139 copy->GetLocalPropertyNames(names, 0); |
| 140 for (int i = 0; i < names->length(); i++) { |
| 141 ASSERT(names->get(i)->IsString()); |
| 142 String* keyString = String::cast(names->get(i)); |
| 143 PropertyAttributes attributes = copy->GetLocalPropertyAttribute(keyString)
; |
| 144 // Only deep copy fields from the object literal expression. |
| 145 // In particular, don't try to copy the length attribute of |
| 146 // an array. |
| 147 if (attributes != NONE) continue; |
| 148 Object* value = copy->GetProperty(keyString, &attributes); |
| 149 ASSERT(!value->IsFailure()); |
| 150 if (value->IsJSObject()) { |
| 151 JSObject* jsObject = JSObject::cast(value); |
| 152 result = DeepCopyBoilerplate(jsObject); |
| 153 if (result->IsFailure()) return result; |
| 154 result = copy->SetProperty(keyString, result, NONE); |
| 155 if (result->IsFailure()) return result; |
| 156 } |
| 157 } |
| 158 } |
| 159 |
| 160 // Deep copy local elements. |
| 161 if (copy->HasFastElements()) { |
| 162 FixedArray* elements = copy->elements(); |
| 163 WriteBarrierMode mode = elements->GetWriteBarrierMode(); |
| 164 for (int i = 0; i < elements->length(); i++) { |
| 165 Object* value = elements->get(i); |
| 166 if (value->IsJSObject()) { |
| 167 JSObject* jsObject = JSObject::cast(value); |
| 168 result = DeepCopyBoilerplate(jsObject); |
| 169 if (result->IsFailure()) return result; |
| 170 elements->set(i, result, mode); |
| 171 } |
| 172 } |
| 173 } else { |
| 174 Dictionary* element_dictionary = copy->element_dictionary(); |
| 175 int capacity = element_dictionary->Capacity(); |
| 176 for (int i = 0; i < capacity; i++) { |
| 177 Object* k = element_dictionary->KeyAt(i); |
| 178 if (element_dictionary->IsKey(k)) { |
| 179 Object* value = element_dictionary->ValueAt(i); |
| 180 if (value->IsJSObject()) { |
| 181 JSObject* jsObject = JSObject::cast(value); |
| 182 result = DeepCopyBoilerplate(jsObject); |
| 183 if (result->IsFailure()) return result; |
| 184 element_dictionary->ValueAtPut(i, result); |
| 185 } |
| 186 } |
| 187 } |
| 188 } |
| 189 return copy; |
| 190 } |
| 191 |
| 192 |
| 193 static Object* Runtime_CloneLiteralBoilerplate(Arguments args) { |
| 194 CONVERT_CHECKED(JSObject, boilerplate, args[0]); |
| 195 return DeepCopyBoilerplate(boilerplate); |
| 196 } |
| 197 |
| 198 |
| 199 static Object* Runtime_CloneShallowLiteralBoilerplate(Arguments args) { |
| 97 CONVERT_CHECKED(JSObject, boilerplate, args[0]); | 200 CONVERT_CHECKED(JSObject, boilerplate, args[0]); |
| 98 return Heap::CopyJSObject(boilerplate); | 201 return Heap::CopyJSObject(boilerplate); |
| 99 } | 202 } |
| 100 | 203 |
| 101 | 204 |
| 102 static Handle<Map> ComputeObjectLiteralMap( | 205 static Handle<Map> ComputeObjectLiteralMap( |
| 103 Handle<Context> context, | 206 Handle<Context> context, |
| 104 Handle<FixedArray> constant_properties, | 207 Handle<FixedArray> constant_properties, |
| 105 bool* is_result_from_cache) { | 208 bool* is_result_from_cache) { |
| 106 int number_of_properties = constant_properties->length() / 2; | 209 int number_of_properties = constant_properties->length() / 2; |
| (...skipping 18 matching lines...) Expand all Loading... |
| 125 return Factory::ObjectLiteralMapFromCache(context, keys); | 228 return Factory::ObjectLiteralMapFromCache(context, keys); |
| 126 } | 229 } |
| 127 } | 230 } |
| 128 *is_result_from_cache = false; | 231 *is_result_from_cache = false; |
| 129 return Factory::CopyMap( | 232 return Factory::CopyMap( |
| 130 Handle<Map>(context->object_function()->initial_map()), | 233 Handle<Map>(context->object_function()->initial_map()), |
| 131 number_of_properties); | 234 number_of_properties); |
| 132 } | 235 } |
| 133 | 236 |
| 134 | 237 |
| 135 static Object* Runtime_CreateObjectLiteralBoilerplate(Arguments args) { | 238 static Handle<Object> CreateLiteralBoilerplate( |
| 136 HandleScope scope; | 239 Handle<FixedArray> literals, |
| 137 ASSERT(args.length() == 3); | 240 Handle<FixedArray> constant_properties); |
| 138 // Copy the arguments. | |
| 139 Handle<FixedArray> literals = args.at<FixedArray>(0); | |
| 140 int literals_index = Smi::cast(args[1])->value(); | |
| 141 Handle<FixedArray> constant_properties = args.at<FixedArray>(2); | |
| 142 | 241 |
| 242 |
| 243 static Handle<Object> CreateObjectLiteralBoilerplate( |
| 244 Handle<FixedArray> literals, |
| 245 Handle<FixedArray> constant_properties) { |
| 143 // Get the global context from the literals array. This is the | 246 // Get the global context from the literals array. This is the |
| 144 // context in which the function was created and we use the object | 247 // context in which the function was created and we use the object |
| 145 // function from this context to create the object literal. We do | 248 // function from this context to create the object literal. We do |
| 146 // not use the object function from the current global context | 249 // not use the object function from the current global context |
| 147 // because this might be the object function from another context | 250 // because this might be the object function from another context |
| 148 // which we should not have access to. | 251 // which we should not have access to. |
| 149 Handle<Context> context = | 252 Handle<Context> context = |
| 150 Handle<Context>(JSFunction::GlobalContextFromLiterals(*literals)); | 253 Handle<Context>(JSFunction::GlobalContextFromLiterals(*literals)); |
| 151 | 254 |
| 152 bool is_result_from_cache; | 255 bool is_result_from_cache; |
| 153 Handle<Map> map = ComputeObjectLiteralMap(context, | 256 Handle<Map> map = ComputeObjectLiteralMap(context, |
| 154 constant_properties, | 257 constant_properties, |
| 155 &is_result_from_cache); | 258 &is_result_from_cache); |
| 156 | 259 |
| 157 Handle<JSObject> boilerplate = Factory::NewJSObjectFromMap(map); | 260 Handle<JSObject> boilerplate = Factory::NewJSObjectFromMap(map); |
| 158 { // Add the constant properties to the boilerplate. | 261 { // Add the constant properties to the boilerplate. |
| 159 int length = constant_properties->length(); | 262 int length = constant_properties->length(); |
| 160 OptimizedObjectForAddingMultipleProperties opt(boilerplate, | 263 OptimizedObjectForAddingMultipleProperties opt(boilerplate, |
| 161 !is_result_from_cache); | 264 !is_result_from_cache); |
| 162 for (int index = 0; index < length; index +=2) { | 265 for (int index = 0; index < length; index +=2) { |
| 163 Handle<Object> key(constant_properties->get(index+0)); | 266 Handle<Object> key(constant_properties->get(index+0)); |
| 164 Handle<Object> value(constant_properties->get(index+1)); | 267 Handle<Object> value(constant_properties->get(index+1)); |
| 268 if (value->IsFixedArray()) { |
| 269 // The value contains the constant_properties of a |
| 270 // simple object literal. |
| 271 Handle<FixedArray> array = Handle<FixedArray>::cast(value); |
| 272 value = CreateLiteralBoilerplate(literals, array); |
| 273 if (value.is_null()) return value; |
| 274 } |
| 165 Handle<Object> result; | 275 Handle<Object> result; |
| 166 uint32_t element_index = 0; | 276 uint32_t element_index = 0; |
| 167 if (key->IsSymbol()) { | 277 if (key->IsSymbol()) { |
| 168 // If key is a symbol it is not an array element. | 278 // If key is a symbol it is not an array element. |
| 169 Handle<String> name(String::cast(*key)); | 279 Handle<String> name(String::cast(*key)); |
| 170 ASSERT(!name->AsArrayIndex(&element_index)); | 280 ASSERT(!name->AsArrayIndex(&element_index)); |
| 171 result = SetProperty(boilerplate, name, value, NONE); | 281 result = SetProperty(boilerplate, name, value, NONE); |
| 172 } else if (Array::IndexFromObject(*key, &element_index)) { | 282 } else if (Array::IndexFromObject(*key, &element_index)) { |
| 173 // Array index (uint32). | 283 // Array index (uint32). |
| 174 result = SetElement(boilerplate, element_index, value); | 284 result = SetElement(boilerplate, element_index, value); |
| 175 } else { | 285 } else { |
| 176 // Non-uint32 number. | 286 // Non-uint32 number. |
| 177 ASSERT(key->IsNumber()); | 287 ASSERT(key->IsNumber()); |
| 178 double num = key->Number(); | 288 double num = key->Number(); |
| 179 char arr[100]; | 289 char arr[100]; |
| 180 Vector<char> buffer(arr, ARRAY_SIZE(arr)); | 290 Vector<char> buffer(arr, ARRAY_SIZE(arr)); |
| 181 const char* str = DoubleToCString(num, buffer); | 291 const char* str = DoubleToCString(num, buffer); |
| 182 Handle<String> name = Factory::NewStringFromAscii(CStrVector(str)); | 292 Handle<String> name = Factory::NewStringFromAscii(CStrVector(str)); |
| 183 result = SetProperty(boilerplate, name, value, NONE); | 293 result = SetProperty(boilerplate, name, value, NONE); |
| 184 } | 294 } |
| 185 // If setting the property on the boilerplate throws an | 295 // If setting the property on the boilerplate throws an |
| 186 // exception, the exception is converted to an empty handle in | 296 // exception, the exception is converted to an empty handle in |
| 187 // the handle based operations. In that case, we need to | 297 // the handle based operations. In that case, we need to |
| 188 // convert back to an exception. | 298 // convert back to an exception. |
| 189 if (result.is_null()) return Failure::Exception(); | 299 if (result.is_null()) return result; |
| 190 } | 300 } |
| 191 } | 301 } |
| 192 | 302 |
| 193 // Update the functions literal and return the boilerplate. | 303 return boilerplate; |
| 194 literals->set(literals_index, *boilerplate); | |
| 195 | |
| 196 return *boilerplate; | |
| 197 } | 304 } |
| 198 | 305 |
| 199 | 306 |
| 200 static Object* Runtime_CreateArrayLiteral(Arguments args) { | 307 static Handle<Object> CreateArrayLiteralBoilerplate( |
| 308 Handle<FixedArray> literals, |
| 309 Handle<FixedArray> elements) { |
| 310 // Create the JSArray. |
| 311 Handle<JSFunction> constructor( |
| 312 JSFunction::GlobalContextFromLiterals(*literals)->array_function()); |
| 313 Handle<Object> object = Factory::NewJSObject(constructor); |
| 314 |
| 315 Handle<Object> copied_elements = Factory::CopyFixedArray(elements); |
| 316 |
| 317 Handle<FixedArray> content = Handle<FixedArray>::cast(copied_elements); |
| 318 for (int i = 0; i < content->length(); i++) { |
| 319 if (content->get(i)->IsFixedArray()) { |
| 320 // The value contains the constant_properties of a |
| 321 // simple object literal. |
| 322 Handle<FixedArray> fa(FixedArray::cast(content->get(i))); |
| 323 Handle<Object> result = |
| 324 CreateLiteralBoilerplate(literals, fa); |
| 325 if (result.is_null()) return result; |
| 326 content->set(i, *result); |
| 327 } |
| 328 } |
| 329 |
| 330 // Set the elements. |
| 331 Handle<JSArray>::cast(object)->SetContent(*content); |
| 332 return object; |
| 333 } |
| 334 |
| 335 |
| 336 static Handle<Object> CreateLiteralBoilerplate( |
| 337 Handle<FixedArray> literals, |
| 338 Handle<FixedArray> array) { |
| 339 Handle<FixedArray> elements = CompileTimeValue::GetElements(array); |
| 340 switch (CompileTimeValue::GetType(array)) { |
| 341 case CompileTimeValue::OBJECT_LITERAL: |
| 342 return CreateObjectLiteralBoilerplate(literals, elements); |
| 343 case CompileTimeValue::ARRAY_LITERAL: |
| 344 return CreateArrayLiteralBoilerplate(literals, elements); |
| 345 default: |
| 346 UNREACHABLE(); |
| 347 return Handle<Object>::null(); |
| 348 } |
| 349 } |
| 350 |
| 351 |
| 352 static Object* Runtime_CreateObjectLiteralBoilerplate(Arguments args) { |
| 353 HandleScope scope; |
| 354 ASSERT(args.length() == 3); |
| 355 // Copy the arguments. |
| 356 CONVERT_ARG_CHECKED(FixedArray, literals, 0); |
| 357 CONVERT_SMI_CHECKED(literals_index, args[1]); |
| 358 CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2); |
| 359 |
| 360 Handle<Object> result = |
| 361 CreateObjectLiteralBoilerplate(literals, constant_properties); |
| 362 |
| 363 if (result.is_null()) return Failure::Exception(); |
| 364 |
| 365 // Update the functions literal and return the boilerplate. |
| 366 literals->set(literals_index, *result); |
| 367 |
| 368 return *result; |
| 369 } |
| 370 |
| 371 |
| 372 static Object* Runtime_CreateArrayLiteralBoilerplate(Arguments args) { |
| 201 // Takes a FixedArray of elements containing the literal elements of | 373 // Takes a FixedArray of elements containing the literal elements of |
| 202 // the array literal and produces JSArray with those elements. | 374 // the array literal and produces JSArray with those elements. |
| 203 // Additionally takes the literals array of the surrounding function | 375 // Additionally takes the literals array of the surrounding function |
| 204 // which contains the context from which to get the Array function | 376 // which contains the context from which to get the Array function |
| 205 // to use for creating the array literal. | 377 // to use for creating the array literal. |
| 206 ASSERT(args.length() == 2); | 378 HandleScope scope; |
| 207 CONVERT_CHECKED(FixedArray, elements, args[0]); | 379 ASSERT(args.length() == 3); |
| 208 CONVERT_CHECKED(FixedArray, literals, args[1]); | 380 CONVERT_ARG_CHECKED(FixedArray, literals, 0); |
| 209 JSFunction* constructor = | 381 CONVERT_SMI_CHECKED(literals_index, args[1]); |
| 210 JSFunction::GlobalContextFromLiterals(literals)->array_function(); | 382 CONVERT_ARG_CHECKED(FixedArray, elements, 2); |
| 211 // Create the JSArray. | |
| 212 Object* object = Heap::AllocateJSObject(constructor); | |
| 213 if (object->IsFailure()) return object; | |
| 214 | 383 |
| 215 // Copy the elements. | 384 Handle<Object> object = CreateArrayLiteralBoilerplate(literals, elements); |
| 216 Object* content = elements->Copy(); | 385 if (object.is_null()) return Failure::Exception(); |
| 217 if (content->IsFailure()) return content; | |
| 218 | 386 |
| 219 // Set the elements. | 387 // Update the functions literal and return the boilerplate. |
| 220 JSArray::cast(object)->SetContent(FixedArray::cast(content)); | 388 literals->set(literals_index, *object); |
| 221 return object; | 389 return *object; |
| 222 } | 390 } |
| 223 | 391 |
| 224 | 392 |
| 225 static Object* Runtime_CreateCatchExtensionObject(Arguments args) { | 393 static Object* Runtime_CreateCatchExtensionObject(Arguments args) { |
| 226 ASSERT(args.length() == 2); | 394 ASSERT(args.length() == 2); |
| 227 CONVERT_CHECKED(String, key, args[0]); | 395 CONVERT_CHECKED(String, key, args[0]); |
| 228 Object* value = args[1]; | 396 Object* value = args[1]; |
| 229 // Create a catch context extension object. | 397 // Create a catch context extension object. |
| 230 JSFunction* constructor = | 398 JSFunction* constructor = |
| 231 Top::context()->global_context()->context_extension_function(); | 399 Top::context()->global_context()->context_extension_function(); |
| (...skipping 6495 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 6727 } else { | 6895 } else { |
| 6728 // Handle last resort GC and make sure to allow future allocations | 6896 // Handle last resort GC and make sure to allow future allocations |
| 6729 // to grow the heap without causing GCs (if possible). | 6897 // to grow the heap without causing GCs (if possible). |
| 6730 Counters::gc_last_resort_from_js.Increment(); | 6898 Counters::gc_last_resort_from_js.Increment(); |
| 6731 Heap::CollectAllGarbage(); | 6899 Heap::CollectAllGarbage(); |
| 6732 } | 6900 } |
| 6733 } | 6901 } |
| 6734 | 6902 |
| 6735 | 6903 |
| 6736 } } // namespace v8::internal | 6904 } } // namespace v8::internal |
| OLD | NEW |