OLD | NEW |
1 // Copyright 2010 the V8 project authors. All rights reserved. | 1 // Copyright 2010 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 2477 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2488 // Load a writable copy of the function of this activation in a | 2488 // Load a writable copy of the function of this activation in a |
2489 // register. | 2489 // register. |
2490 frame_->PushFunction(); | 2490 frame_->PushFunction(); |
2491 Result literals = frame_->Pop(); | 2491 Result literals = frame_->Pop(); |
2492 literals.ToRegister(); | 2492 literals.ToRegister(); |
2493 frame_->Spill(literals.reg()); | 2493 frame_->Spill(literals.reg()); |
2494 | 2494 |
2495 // Load the literals array of the function. | 2495 // Load the literals array of the function. |
2496 __ movq(literals.reg(), | 2496 __ movq(literals.reg(), |
2497 FieldOperand(literals.reg(), JSFunction::kLiteralsOffset)); | 2497 FieldOperand(literals.reg(), JSFunction::kLiteralsOffset)); |
2498 // Literal array. | 2498 |
2499 frame_->Push(&literals); | 2499 frame_->Push(&literals); |
2500 // Literal index. | |
2501 frame_->Push(Smi::FromInt(node->literal_index())); | 2500 frame_->Push(Smi::FromInt(node->literal_index())); |
2502 // Constant elements. | |
2503 frame_->Push(node->constant_elements()); | 2501 frame_->Push(node->constant_elements()); |
| 2502 int length = node->values()->length(); |
2504 Result clone; | 2503 Result clone; |
2505 if (node->depth() > 1) { | 2504 if (node->depth() > 1) { |
2506 clone = frame_->CallRuntime(Runtime::kCreateArrayLiteral, 3); | 2505 clone = frame_->CallRuntime(Runtime::kCreateArrayLiteral, 3); |
| 2506 } else if (length > FastCloneShallowArrayStub::kMaximumLength) { |
| 2507 clone = frame_->CallRuntime(Runtime::kCreateArrayLiteralShallow, 3); |
2507 } else { | 2508 } else { |
2508 clone = frame_->CallRuntime(Runtime::kCreateArrayLiteralShallow, 3); | 2509 FastCloneShallowArrayStub stub(length); |
| 2510 clone = frame_->CallStub(&stub, 3); |
2509 } | 2511 } |
2510 frame_->Push(&clone); | 2512 frame_->Push(&clone); |
2511 | 2513 |
2512 // Generate code to set the elements in the array that are not | 2514 // Generate code to set the elements in the array that are not |
2513 // literals. | 2515 // literals. |
2514 for (int i = 0; i < node->values()->length(); i++) { | 2516 for (int i = 0; i < node->values()->length(); i++) { |
2515 Expression* value = node->values()->at(i); | 2517 Expression* value = node->values()->at(i); |
2516 | 2518 |
2517 // If value is a literal the property value is already set in the | 2519 // If value is a literal the property value is already set in the |
2518 // boilerplate object. | 2520 // boilerplate object. |
(...skipping 3734 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6253 // Return and remove the on-stack parameter. | 6255 // Return and remove the on-stack parameter. |
6254 __ movq(rsi, rax); | 6256 __ movq(rsi, rax); |
6255 __ ret(1 * kPointerSize); | 6257 __ ret(1 * kPointerSize); |
6256 | 6258 |
6257 // Need to collect. Call into runtime system. | 6259 // Need to collect. Call into runtime system. |
6258 __ bind(&gc); | 6260 __ bind(&gc); |
6259 __ TailCallRuntime(ExternalReference(Runtime::kNewContext), 1, 1); | 6261 __ TailCallRuntime(ExternalReference(Runtime::kNewContext), 1, 1); |
6260 } | 6262 } |
6261 | 6263 |
6262 | 6264 |
| 6265 void FastCloneShallowArrayStub::Generate(MacroAssembler* masm) { |
| 6266 // Stack layout on entry: |
| 6267 // |
| 6268 // [rsp + kPointerSize]: constant elements. |
| 6269 // [rsp + (2 * kPointerSize)]: literal index. |
| 6270 // [rsp + (3 * kPointerSize)]: literals array. |
| 6271 |
| 6272 // All sizes here are multiples of kPointerSize. |
| 6273 int elements_size = (length_ > 0) ? FixedArray::SizeFor(length_) : 0; |
| 6274 int size = JSArray::kSize + elements_size; |
| 6275 |
| 6276 // Load boilerplate object into rcx and check if we need to create a |
| 6277 // boilerplate. |
| 6278 Label slow_case; |
| 6279 __ movq(rcx, Operand(rsp, 3 * kPointerSize)); |
| 6280 __ movq(rax, Operand(rsp, 2 * kPointerSize)); |
| 6281 SmiIndex index = masm->SmiToIndex(rax, rax, kPointerSizeLog2); |
| 6282 __ movq(rcx, |
| 6283 FieldOperand(rcx, index.reg, index.scale, FixedArray::kHeaderSize)); |
| 6284 __ CompareRoot(rcx, Heap::kUndefinedValueRootIndex); |
| 6285 __ j(equal, &slow_case); |
| 6286 |
| 6287 // Allocate both the JS array and the elements array in one big |
| 6288 // allocation. This avoids multiple limit checks. |
| 6289 __ AllocateInNewSpace(size, rax, rbx, rdx, &slow_case, TAG_OBJECT); |
| 6290 |
| 6291 // Copy the JS array part. |
| 6292 for (int i = 0; i < JSArray::kSize; i += kPointerSize) { |
| 6293 if ((i != JSArray::kElementsOffset) || (length_ == 0)) { |
| 6294 __ movq(rbx, FieldOperand(rcx, i)); |
| 6295 __ movq(FieldOperand(rax, i), rbx); |
| 6296 } |
| 6297 } |
| 6298 |
| 6299 if (length_ > 0) { |
| 6300 // Get hold of the elements array of the boilerplate and setup the |
| 6301 // elements pointer in the resulting object. |
| 6302 __ movq(rcx, FieldOperand(rcx, JSArray::kElementsOffset)); |
| 6303 __ lea(rdx, Operand(rax, JSArray::kSize)); |
| 6304 __ movq(FieldOperand(rax, JSArray::kElementsOffset), rdx); |
| 6305 |
| 6306 // Copy the elements array. |
| 6307 for (int i = 0; i < elements_size; i += kPointerSize) { |
| 6308 __ movq(rbx, FieldOperand(rcx, i)); |
| 6309 __ movq(FieldOperand(rdx, i), rbx); |
| 6310 } |
| 6311 } |
| 6312 |
| 6313 // Return and remove the on-stack parameters. |
| 6314 __ ret(3 * kPointerSize); |
| 6315 |
| 6316 __ bind(&slow_case); |
| 6317 ExternalReference runtime(Runtime::kCreateArrayLiteralShallow); |
| 6318 __ TailCallRuntime(runtime, 3, 1); |
| 6319 } |
| 6320 |
| 6321 |
6263 void ToBooleanStub::Generate(MacroAssembler* masm) { | 6322 void ToBooleanStub::Generate(MacroAssembler* masm) { |
6264 Label false_result, true_result, not_string; | 6323 Label false_result, true_result, not_string; |
6265 __ movq(rax, Operand(rsp, 1 * kPointerSize)); | 6324 __ movq(rax, Operand(rsp, 1 * kPointerSize)); |
6266 | 6325 |
6267 // 'null' => false. | 6326 // 'null' => false. |
6268 __ CompareRoot(rax, Heap::kNullValueRootIndex); | 6327 __ CompareRoot(rax, Heap::kNullValueRootIndex); |
6269 __ j(equal, &false_result); | 6328 __ j(equal, &false_result); |
6270 | 6329 |
6271 // Get the map and type of the heap object. | 6330 // Get the map and type of the heap object. |
6272 // We don't use CmpObjectType because we manipulate the type field. | 6331 // We don't use CmpObjectType because we manipulate the type field. |
(...skipping 2965 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9238 // Call the function from C++. | 9297 // Call the function from C++. |
9239 return FUNCTION_CAST<ModuloFunction>(buffer); | 9298 return FUNCTION_CAST<ModuloFunction>(buffer); |
9240 } | 9299 } |
9241 | 9300 |
9242 #endif | 9301 #endif |
9243 | 9302 |
9244 | 9303 |
9245 #undef __ | 9304 #undef __ |
9246 | 9305 |
9247 } } // namespace v8::internal | 9306 } } // namespace v8::internal |
OLD | NEW |