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 229 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
240 } | 240 } |
241 | 241 |
242 | 242 |
243 static Handle<Object> CreateLiteralBoilerplate( | 243 static Handle<Object> CreateLiteralBoilerplate( |
244 Handle<FixedArray> literals, | 244 Handle<FixedArray> literals, |
245 Handle<FixedArray> constant_properties); | 245 Handle<FixedArray> constant_properties); |
246 | 246 |
247 | 247 |
248 static Handle<Object> CreateObjectLiteralBoilerplate( | 248 static Handle<Object> CreateObjectLiteralBoilerplate( |
249 Handle<FixedArray> literals, | 249 Handle<FixedArray> literals, |
250 Handle<FixedArray> constant_properties) { | 250 Handle<FixedArray> constant_properties, |
251 bool should_have_fast_elements) { | |
251 // Get the global context from the literals array. This is the | 252 // Get the global context from the literals array. This is the |
252 // context in which the function was created and we use the object | 253 // context in which the function was created and we use the object |
253 // function from this context to create the object literal. We do | 254 // function from this context to create the object literal. We do |
254 // not use the object function from the current global context | 255 // not use the object function from the current global context |
255 // because this might be the object function from another context | 256 // because this might be the object function from another context |
256 // which we should not have access to. | 257 // which we should not have access to. |
257 Handle<Context> context = | 258 Handle<Context> context = |
258 Handle<Context>(JSFunction::GlobalContextFromLiterals(*literals)); | 259 Handle<Context>(JSFunction::GlobalContextFromLiterals(*literals)); |
259 | 260 |
260 bool is_result_from_cache; | 261 bool is_result_from_cache; |
261 Handle<Map> map = ComputeObjectLiteralMap(context, | 262 Handle<Map> map = ComputeObjectLiteralMap(context, |
262 constant_properties, | 263 constant_properties, |
263 &is_result_from_cache); | 264 &is_result_from_cache); |
264 | 265 |
265 Handle<JSObject> boilerplate = Factory::NewJSObjectFromMap(map); | 266 Handle<JSObject> boilerplate = Factory::NewJSObjectFromMap(map); |
267 | |
268 // Normalize the elements of the boilerplate to save space if needed. | |
269 if (!should_have_fast_elements) NormalizeElements(boilerplate); | |
270 | |
266 { // Add the constant properties to the boilerplate. | 271 { // Add the constant properties to the boilerplate. |
267 int length = constant_properties->length(); | 272 int length = constant_properties->length(); |
268 OptimizedObjectForAddingMultipleProperties opt(boilerplate, | 273 OptimizedObjectForAddingMultipleProperties opt(boilerplate, |
269 length / 2, | 274 length / 2, |
270 !is_result_from_cache); | 275 !is_result_from_cache); |
271 for (int index = 0; index < length; index +=2) { | 276 for (int index = 0; index < length; index +=2) { |
272 Handle<Object> key(constant_properties->get(index+0)); | 277 Handle<Object> key(constant_properties->get(index+0)); |
273 Handle<Object> value(constant_properties->get(index+1)); | 278 Handle<Object> value(constant_properties->get(index+1)); |
274 if (value->IsFixedArray()) { | 279 if (value->IsFixedArray()) { |
275 // The value contains the constant_properties of a | 280 // The value contains the constant_properties of a |
(...skipping 61 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
337 Handle<JSArray>::cast(object)->SetContent(*content); | 342 Handle<JSArray>::cast(object)->SetContent(*content); |
338 return object; | 343 return object; |
339 } | 344 } |
340 | 345 |
341 | 346 |
342 static Handle<Object> CreateLiteralBoilerplate( | 347 static Handle<Object> CreateLiteralBoilerplate( |
343 Handle<FixedArray> literals, | 348 Handle<FixedArray> literals, |
344 Handle<FixedArray> array) { | 349 Handle<FixedArray> array) { |
345 Handle<FixedArray> elements = CompileTimeValue::GetElements(array); | 350 Handle<FixedArray> elements = CompileTimeValue::GetElements(array); |
346 switch (CompileTimeValue::GetType(array)) { | 351 switch (CompileTimeValue::GetType(array)) { |
347 case CompileTimeValue::OBJECT_LITERAL: | 352 case CompileTimeValue::OBJECT_LITERAL_FAST_ELEMENTS: |
348 return CreateObjectLiteralBoilerplate(literals, elements); | 353 return CreateObjectLiteralBoilerplate(literals, elements, true); |
354 case CompileTimeValue::OBJECT_LITERAL_SLOW_ELEMENTS: | |
355 return CreateObjectLiteralBoilerplate(literals, elements, false); | |
349 case CompileTimeValue::ARRAY_LITERAL: | 356 case CompileTimeValue::ARRAY_LITERAL: |
350 return CreateArrayLiteralBoilerplate(literals, elements); | 357 return CreateArrayLiteralBoilerplate(literals, elements); |
351 default: | 358 default: |
352 UNREACHABLE(); | 359 UNREACHABLE(); |
353 return Handle<Object>::null(); | 360 return Handle<Object>::null(); |
354 } | 361 } |
355 } | 362 } |
356 | 363 |
357 | 364 |
358 static Object* Runtime_CreateObjectLiteralBoilerplate(Arguments args) { | |
359 HandleScope scope; | |
360 ASSERT(args.length() == 3); | |
361 // Copy the arguments. | |
362 CONVERT_ARG_CHECKED(FixedArray, literals, 0); | |
363 CONVERT_SMI_CHECKED(literals_index, args[1]); | |
364 CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2); | |
365 | |
366 Handle<Object> result = | |
367 CreateObjectLiteralBoilerplate(literals, constant_properties); | |
368 | |
369 if (result.is_null()) return Failure::Exception(); | |
370 | |
371 // Update the functions literal and return the boilerplate. | |
372 literals->set(literals_index, *result); | |
373 | |
374 return *result; | |
375 } | |
376 | |
377 | |
378 static Object* Runtime_CreateArrayLiteralBoilerplate(Arguments args) { | 365 static Object* Runtime_CreateArrayLiteralBoilerplate(Arguments args) { |
379 // Takes a FixedArray of elements containing the literal elements of | 366 // Takes a FixedArray of elements containing the literal elements of |
380 // the array literal and produces JSArray with those elements. | 367 // the array literal and produces JSArray with those elements. |
381 // Additionally takes the literals array of the surrounding function | 368 // Additionally takes the literals array of the surrounding function |
382 // which contains the context from which to get the Array function | 369 // which contains the context from which to get the Array function |
383 // to use for creating the array literal. | 370 // to use for creating the array literal. |
384 HandleScope scope; | 371 HandleScope scope; |
385 ASSERT(args.length() == 3); | 372 ASSERT(args.length() == 3); |
386 CONVERT_ARG_CHECKED(FixedArray, literals, 0); | 373 CONVERT_ARG_CHECKED(FixedArray, literals, 0); |
387 CONVERT_SMI_CHECKED(literals_index, args[1]); | 374 CONVERT_SMI_CHECKED(literals_index, args[1]); |
388 CONVERT_ARG_CHECKED(FixedArray, elements, 2); | 375 CONVERT_ARG_CHECKED(FixedArray, elements, 2); |
389 | 376 |
390 Handle<Object> object = CreateArrayLiteralBoilerplate(literals, elements); | 377 Handle<Object> object = CreateArrayLiteralBoilerplate(literals, elements); |
391 if (object.is_null()) return Failure::Exception(); | 378 if (object.is_null()) return Failure::Exception(); |
392 | 379 |
393 // Update the functions literal and return the boilerplate. | 380 // Update the functions literal and return the boilerplate. |
394 literals->set(literals_index, *object); | 381 literals->set(literals_index, *object); |
395 return *object; | 382 return *object; |
396 } | 383 } |
397 | 384 |
398 | 385 |
399 static Object* Runtime_CreateObjectLiteral(Arguments args) { | 386 static Object* Runtime_CreateObjectLiteral(Arguments args) { |
400 HandleScope scope; | 387 HandleScope scope; |
401 ASSERT(args.length() == 3); | 388 ASSERT(args.length() == 4); |
402 CONVERT_ARG_CHECKED(FixedArray, literals, 0); | 389 CONVERT_ARG_CHECKED(FixedArray, literals, 0); |
403 CONVERT_SMI_CHECKED(literals_index, args[1]); | 390 CONVERT_SMI_CHECKED(literals_index, args[1]); |
404 CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2); | 391 CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2); |
392 CONVERT_SMI_CHECKED(fast_elements, args[3]); | |
Søren Thygesen Gjesse
2010/03/11 08:28:59
Why is this argument not a Boolean object? To save
| |
393 bool should_have_fast_elements = fast_elements == 1; | |
405 | 394 |
406 // Check if boilerplate exists. If not, create it first. | 395 // Check if boilerplate exists. If not, create it first. |
407 Handle<Object> boilerplate(literals->get(literals_index)); | 396 Handle<Object> boilerplate(literals->get(literals_index)); |
408 if (*boilerplate == Heap::undefined_value()) { | 397 if (*boilerplate == Heap::undefined_value()) { |
409 boilerplate = CreateObjectLiteralBoilerplate(literals, constant_properties); | 398 boilerplate = CreateObjectLiteralBoilerplate(literals, |
399 constant_properties, | |
400 should_have_fast_elements); | |
410 if (boilerplate.is_null()) return Failure::Exception(); | 401 if (boilerplate.is_null()) return Failure::Exception(); |
411 // Update the functions literal and return the boilerplate. | 402 // Update the functions literal and return the boilerplate. |
412 literals->set(literals_index, *boilerplate); | 403 literals->set(literals_index, *boilerplate); |
413 } | 404 } |
414 return DeepCopyBoilerplate(JSObject::cast(*boilerplate)); | 405 return DeepCopyBoilerplate(JSObject::cast(*boilerplate)); |
415 } | 406 } |
416 | 407 |
417 | 408 |
418 static Object* Runtime_CreateObjectLiteralShallow(Arguments args) { | 409 static Object* Runtime_CreateObjectLiteralShallow(Arguments args) { |
419 HandleScope scope; | 410 HandleScope scope; |
420 ASSERT(args.length() == 3); | 411 ASSERT(args.length() == 4); |
421 CONVERT_ARG_CHECKED(FixedArray, literals, 0); | 412 CONVERT_ARG_CHECKED(FixedArray, literals, 0); |
422 CONVERT_SMI_CHECKED(literals_index, args[1]); | 413 CONVERT_SMI_CHECKED(literals_index, args[1]); |
423 CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2); | 414 CONVERT_ARG_CHECKED(FixedArray, constant_properties, 2); |
415 CONVERT_SMI_CHECKED(fast_elements, args[3]); | |
416 bool should_have_fast_elements = fast_elements == 1; | |
424 | 417 |
425 // Check if boilerplate exists. If not, create it first. | 418 // Check if boilerplate exists. If not, create it first. |
426 Handle<Object> boilerplate(literals->get(literals_index)); | 419 Handle<Object> boilerplate(literals->get(literals_index)); |
427 if (*boilerplate == Heap::undefined_value()) { | 420 if (*boilerplate == Heap::undefined_value()) { |
428 boilerplate = CreateObjectLiteralBoilerplate(literals, constant_properties); | 421 boilerplate = CreateObjectLiteralBoilerplate(literals, |
422 constant_properties, | |
423 should_have_fast_elements); | |
429 if (boilerplate.is_null()) return Failure::Exception(); | 424 if (boilerplate.is_null()) return Failure::Exception(); |
430 // Update the functions literal and return the boilerplate. | 425 // Update the functions literal and return the boilerplate. |
431 literals->set(literals_index, *boilerplate); | 426 literals->set(literals_index, *boilerplate); |
432 } | 427 } |
433 return Heap::CopyJSObject(JSObject::cast(*boilerplate)); | 428 return Heap::CopyJSObject(JSObject::cast(*boilerplate)); |
434 } | 429 } |
435 | 430 |
436 | 431 |
437 static Object* Runtime_CreateArrayLiteral(Arguments args) { | 432 static Object* Runtime_CreateArrayLiteral(Arguments args) { |
438 HandleScope scope; | 433 HandleScope scope; |
(...skipping 8310 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
8749 } else { | 8744 } else { |
8750 // Handle last resort GC and make sure to allow future allocations | 8745 // Handle last resort GC and make sure to allow future allocations |
8751 // to grow the heap without causing GCs (if possible). | 8746 // to grow the heap without causing GCs (if possible). |
8752 Counters::gc_last_resort_from_js.Increment(); | 8747 Counters::gc_last_resort_from_js.Increment(); |
8753 Heap::CollectAllGarbage(false); | 8748 Heap::CollectAllGarbage(false); |
8754 } | 8749 } |
8755 } | 8750 } |
8756 | 8751 |
8757 | 8752 |
8758 } } // namespace v8::internal | 8753 } } // namespace v8::internal |
OLD | NEW |