Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(338)

Side by Side Diff: src/x64/codegen-x64.cc

Issue 507036: Use one runtime call for creating object/array literals in... (Closed) Base URL: http://v8.googlecode.com/svn/branches/bleeding_edge/
Patch Set: '' Created 11 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « src/parser.cc ('k') | src/x64/fast-codegen-x64.cc » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 2344 matching lines...) Expand 10 before | Expand all | Expand 10 after
2355 __ CompareRoot(boilerplate.reg(), Heap::kUndefinedValueRootIndex); 2355 __ CompareRoot(boilerplate.reg(), Heap::kUndefinedValueRootIndex);
2356 deferred->Branch(equal); 2356 deferred->Branch(equal);
2357 deferred->BindExit(); 2357 deferred->BindExit();
2358 literals.Unuse(); 2358 literals.Unuse();
2359 2359
2360 // Push the boilerplate object. 2360 // Push the boilerplate object.
2361 frame_->Push(&boilerplate); 2361 frame_->Push(&boilerplate);
2362 } 2362 }
2363 2363
2364 2364
2365 // Materialize the object literal 'node' in the literals array
2366 // 'literals' of the function. Leave the object boilerplate in
2367 // 'boilerplate'.
2368 class DeferredObjectLiteral: public DeferredCode {
2369 public:
2370 DeferredObjectLiteral(Register boilerplate,
2371 Register literals,
2372 ObjectLiteral* node)
2373 : boilerplate_(boilerplate), literals_(literals), node_(node) {
2374 set_comment("[ DeferredObjectLiteral");
2375 }
2376
2377 void Generate();
2378
2379 private:
2380 Register boilerplate_;
2381 Register literals_;
2382 ObjectLiteral* node_;
2383 };
2384
2385
2386 void DeferredObjectLiteral::Generate() {
2387 // Since the entry is undefined we call the runtime system to
2388 // compute the literal.
2389 // Literal array (0).
2390 __ push(literals_);
2391 // Literal index (1).
2392 __ Push(Smi::FromInt(node_->literal_index()));
2393 // Constant properties (2).
2394 __ Push(node_->constant_properties());
2395 __ CallRuntime(Runtime::kCreateObjectLiteralBoilerplate, 3);
2396 if (!boilerplate_.is(rax)) __ movq(boilerplate_, rax);
2397 }
2398
2399
2400 void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) { 2365 void CodeGenerator::VisitObjectLiteral(ObjectLiteral* node) {
2401 Comment cmnt(masm_, "[ ObjectLiteral"); 2366 Comment cmnt(masm_, "[ ObjectLiteral");
2402 2367
2403 // Retrieve the literals array and check the allocated entry. Begin 2368 // Load a writable copy of the function of this activation in a
2404 // with a writable copy of the function of this activation in a
2405 // register. 2369 // register.
2406 frame_->PushFunction(); 2370 frame_->PushFunction();
2407 Result literals = frame_->Pop(); 2371 Result literals = frame_->Pop();
2408 literals.ToRegister(); 2372 literals.ToRegister();
2409 frame_->Spill(literals.reg()); 2373 frame_->Spill(literals.reg());
2410 2374
2411 // Load the literals array of the function. 2375 // Load the literals array of the function.
2412 __ movq(literals.reg(), 2376 __ movq(literals.reg(),
2413 FieldOperand(literals.reg(), JSFunction::kLiteralsOffset)); 2377 FieldOperand(literals.reg(), JSFunction::kLiteralsOffset));
2414 2378 // Literal array.
2415 // Load the literal at the ast saved index. 2379 frame_->Push(&literals);
2416 Result boilerplate = allocator_->Allocate(); 2380 // Literal index.
2417 ASSERT(boilerplate.is_valid()); 2381 frame_->Push(Smi::FromInt(node->literal_index()));
2418 int literal_offset = 2382 // Constant properties.
2419 FixedArray::kHeaderSize + node->literal_index() * kPointerSize; 2383 frame_->Push(node->constant_properties());
2420 __ movq(boilerplate.reg(), FieldOperand(literals.reg(), literal_offset)); 2384 Result clone;
2421 2385 if (node->depth() > 1) {
2422 // Check whether we need to materialize the object literal boilerplate. 2386 clone = frame_->CallRuntime(Runtime::kCreateObjectLiteral, 3);
2423 // If so, jump to the deferred code passing the literals array. 2387 } else {
2424 DeferredObjectLiteral* deferred = 2388 clone = frame_->CallRuntime(Runtime::kCreateObjectLiteralShallow, 3);
2425 new DeferredObjectLiteral(boilerplate.reg(), literals.reg(), node);
2426 __ CompareRoot(boilerplate.reg(), Heap::kUndefinedValueRootIndex);
2427 deferred->Branch(equal);
2428 deferred->BindExit();
2429 literals.Unuse();
2430
2431 // Push the boilerplate object.
2432 frame_->Push(&boilerplate);
2433 // Clone the boilerplate object.
2434 Runtime::FunctionId clone_function_id = Runtime::kCloneLiteralBoilerplate;
2435 if (node->depth() == 1) {
2436 clone_function_id = Runtime::kCloneShallowLiteralBoilerplate;
2437 } 2389 }
2438 Result clone = frame_->CallRuntime(clone_function_id, 1);
2439 // Push the newly cloned literal object as the result.
2440 frame_->Push(&clone); 2390 frame_->Push(&clone);
2441 2391
2442 for (int i = 0; i < node->properties()->length(); i++) { 2392 for (int i = 0; i < node->properties()->length(); i++) {
2443 ObjectLiteral::Property* property = node->properties()->at(i); 2393 ObjectLiteral::Property* property = node->properties()->at(i);
2444 switch (property->kind()) { 2394 switch (property->kind()) {
2445 case ObjectLiteral::Property::CONSTANT: 2395 case ObjectLiteral::Property::CONSTANT:
2446 break; 2396 break;
2447 case ObjectLiteral::Property::MATERIALIZED_LITERAL: 2397 case ObjectLiteral::Property::MATERIALIZED_LITERAL:
2448 if (CompileTimeValue::IsCompileTimeValue(property->value())) break; 2398 if (CompileTimeValue::IsCompileTimeValue(property->value())) break;
2449 // else fall through. 2399 // else fall through.
(...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after
2489 Result ignored = frame_->CallRuntime(Runtime::kDefineAccessor, 4); 2439 Result ignored = frame_->CallRuntime(Runtime::kDefineAccessor, 4);
2490 // Ignore the result. 2440 // Ignore the result.
2491 break; 2441 break;
2492 } 2442 }
2493 default: UNREACHABLE(); 2443 default: UNREACHABLE();
2494 } 2444 }
2495 } 2445 }
2496 } 2446 }
2497 2447
2498 2448
2499 // Materialize the array literal 'node' in the literals array 'literals'
2500 // of the function. Leave the array boilerplate in 'boilerplate'.
2501 class DeferredArrayLiteral: public DeferredCode {
2502 public:
2503 DeferredArrayLiteral(Register boilerplate,
2504 Register literals,
2505 ArrayLiteral* node)
2506 : boilerplate_(boilerplate), literals_(literals), node_(node) {
2507 set_comment("[ DeferredArrayLiteral");
2508 }
2509
2510 void Generate();
2511
2512 private:
2513 Register boilerplate_;
2514 Register literals_;
2515 ArrayLiteral* node_;
2516 };
2517
2518
2519 void DeferredArrayLiteral::Generate() {
2520 // Since the entry is undefined we call the runtime system to
2521 // compute the literal.
2522 // Literal array (0).
2523 __ push(literals_);
2524 // Literal index (1).
2525 __ Push(Smi::FromInt(node_->literal_index()));
2526 // Constant properties (2).
2527 __ Push(node_->literals());
2528 __ CallRuntime(Runtime::kCreateArrayLiteralBoilerplate, 3);
2529 if (!boilerplate_.is(rax)) __ movq(boilerplate_, rax);
2530 }
2531
2532
2533 void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) { 2449 void CodeGenerator::VisitArrayLiteral(ArrayLiteral* node) {
2534 Comment cmnt(masm_, "[ ArrayLiteral"); 2450 Comment cmnt(masm_, "[ ArrayLiteral");
2535 2451
2536 // Retrieve the literals array and check the allocated entry. Begin 2452 // Load a writable copy of the function of this activation in a
2537 // with a writable copy of the function of this activation in a
2538 // register. 2453 // register.
2539 frame_->PushFunction(); 2454 frame_->PushFunction();
2540 Result literals = frame_->Pop(); 2455 Result literals = frame_->Pop();
2541 literals.ToRegister(); 2456 literals.ToRegister();
2542 frame_->Spill(literals.reg()); 2457 frame_->Spill(literals.reg());
2543 2458
2544 // Load the literals array of the function. 2459 // Load the literals array of the function.
2545 __ movq(literals.reg(), 2460 __ movq(literals.reg(),
2546 FieldOperand(literals.reg(), JSFunction::kLiteralsOffset)); 2461 FieldOperand(literals.reg(), JSFunction::kLiteralsOffset));
2547 2462 // Literal array.
2548 // Load the literal at the ast saved index. 2463 frame_->Push(&literals);
2549 Result boilerplate = allocator_->Allocate(); 2464 // Literal index.
2550 ASSERT(boilerplate.is_valid()); 2465 frame_->Push(Smi::FromInt(node->literal_index()));
2551 int literal_offset = 2466 // Constant elements.
2552 FixedArray::kHeaderSize + node->literal_index() * kPointerSize; 2467 frame_->Push(node->constant_elements());
2553 __ movq(boilerplate.reg(), FieldOperand(literals.reg(), literal_offset)); 2468 Result clone;
2554 2469 if (node->depth() > 1) {
2555 // Check whether we need to materialize the object literal boilerplate. 2470 clone = frame_->CallRuntime(Runtime::kCreateArrayLiteral, 3);
2556 // If so, jump to the deferred code passing the literals array. 2471 } else {
2557 DeferredArrayLiteral* deferred = 2472 clone = frame_->CallRuntime(Runtime::kCreateArrayLiteralShallow, 3);
2558 new DeferredArrayLiteral(boilerplate.reg(), literals.reg(), node);
2559 __ CompareRoot(boilerplate.reg(), Heap::kUndefinedValueRootIndex);
2560 deferred->Branch(equal);
2561 deferred->BindExit();
2562 literals.Unuse();
2563
2564 // Push the resulting array literal boilerplate on the stack.
2565 frame_->Push(&boilerplate);
2566 // Clone the boilerplate object.
2567 Runtime::FunctionId clone_function_id = Runtime::kCloneLiteralBoilerplate;
2568 if (node->depth() == 1) {
2569 clone_function_id = Runtime::kCloneShallowLiteralBoilerplate;
2570 } 2473 }
2571 Result clone = frame_->CallRuntime(clone_function_id, 1);
2572 // Push the newly cloned literal object as the result.
2573 frame_->Push(&clone); 2474 frame_->Push(&clone);
2574 2475
2575 // Generate code to set the elements in the array that are not 2476 // Generate code to set the elements in the array that are not
2576 // literals. 2477 // literals.
2577 for (int i = 0; i < node->values()->length(); i++) { 2478 for (int i = 0; i < node->values()->length(); i++) {
2578 Expression* value = node->values()->at(i); 2479 Expression* value = node->values()->at(i);
2579 2480
2580 // If value is a literal the property value is already set in the 2481 // If value is a literal the property value is already set in the
2581 // boilerplate object. 2482 // boilerplate object.
2582 if (value->AsLiteral() != NULL) continue; 2483 if (value->AsLiteral() != NULL) continue;
(...skipping 5560 matching lines...) Expand 10 before | Expand all | Expand 10 after
8143 masm.GetCode(&desc); 8044 masm.GetCode(&desc);
8144 // Call the function from C++. 8045 // Call the function from C++.
8145 return FUNCTION_CAST<ModuloFunction>(buffer); 8046 return FUNCTION_CAST<ModuloFunction>(buffer);
8146 } 8047 }
8147 8048
8148 #endif 8049 #endif
8149 8050
8150 #undef __ 8051 #undef __
8151 8052
8152 } } // namespace v8::internal 8053 } } // namespace v8::internal
OLDNEW
« no previous file with comments | « src/parser.cc ('k') | src/x64/fast-codegen-x64.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698