Chromium Code Reviews| 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 |