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 2220 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2231 | 2231 |
2232 void CodeGenerator::InstantiateFunction( | 2232 void CodeGenerator::InstantiateFunction( |
2233 Handle<SharedFunctionInfo> function_info) { | 2233 Handle<SharedFunctionInfo> function_info) { |
2234 // The inevitable call will sync frame elements to memory anyway, so | 2234 // The inevitable call will sync frame elements to memory anyway, so |
2235 // we do it eagerly to allow us to push the arguments directly into | 2235 // we do it eagerly to allow us to push the arguments directly into |
2236 // place. | 2236 // place. |
2237 frame_->SyncRange(0, frame_->element_count() - 1); | 2237 frame_->SyncRange(0, frame_->element_count() - 1); |
2238 | 2238 |
2239 // Use the fast case closure allocation code that allocates in new | 2239 // Use the fast case closure allocation code that allocates in new |
2240 // space for nested functions that don't need literals cloning. | 2240 // space for nested functions that don't need literals cloning. |
2241 if (false && scope()->is_function_scope() && | 2241 if (scope()->is_function_scope() && function_info->num_literals() == 0) { |
2242 function_info->num_literals() == 0) { | |
2243 FastNewClosureStub stub; | 2242 FastNewClosureStub stub; |
2244 frame_->Push(function_info); | 2243 frame_->Push(function_info); |
2245 Result answer = frame_->CallStub(&stub, 1); | 2244 Result answer = frame_->CallStub(&stub, 1); |
2246 frame_->Push(&answer); | 2245 frame_->Push(&answer); |
2247 } else { | 2246 } else { |
2248 // Call the runtime to instantiate the function boilerplate | 2247 // Call the runtime to instantiate the function boilerplate |
2249 // object. | 2248 // object. |
2250 frame_->EmitPush(rsi); | 2249 frame_->EmitPush(rsi); |
2251 frame_->EmitPush(function_info); | 2250 frame_->EmitPush(function_info); |
2252 Result result = frame_->CallRuntime(Runtime::kNewClosure, 2); | 2251 Result result = frame_->CallRuntime(Runtime::kNewClosure, 2); |
(...skipping 4101 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
6354 break; | 6353 break; |
6355 } | 6354 } |
6356 | 6355 |
6357 default: | 6356 default: |
6358 UNREACHABLE(); | 6357 UNREACHABLE(); |
6359 } | 6358 } |
6360 } | 6359 } |
6361 | 6360 |
6362 | 6361 |
6363 void FastNewClosureStub::Generate(MacroAssembler* masm) { | 6362 void FastNewClosureStub::Generate(MacroAssembler* masm) { |
6364 // Clone the boilerplate in new space. Set the context to the | 6363 // Create a new closure from the given function info in new |
6365 // current context in rsi. | 6364 // space. Set the context to the current context in rsi. |
6366 Label gc; | 6365 Label gc; |
6367 __ AllocateInNewSpace(JSFunction::kSize, rax, rbx, rcx, &gc, TAG_OBJECT); | 6366 __ AllocateInNewSpace(JSFunction::kSize, rax, rbx, rcx, &gc, TAG_OBJECT); |
6368 | 6367 |
6369 // Get the boilerplate function from the stack. | 6368 // Get the function info from the stack. |
6370 __ movq(rdx, Operand(rsp, 1 * kPointerSize)); | 6369 __ movq(rdx, Operand(rsp, 1 * kPointerSize)); |
6371 | 6370 |
6372 // Compute the function map in the current global context and set that | 6371 // Compute the function map in the current global context and set that |
6373 // as the map of the allocated object. | 6372 // as the map of the allocated object. |
6374 __ movq(rcx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX))); | 6373 __ movq(rcx, Operand(rsi, Context::SlotOffset(Context::GLOBAL_INDEX))); |
6375 __ movq(rcx, FieldOperand(rcx, GlobalObject::kGlobalContextOffset)); | 6374 __ movq(rcx, FieldOperand(rcx, GlobalObject::kGlobalContextOffset)); |
6376 __ movq(rcx, Operand(rcx, Context::SlotOffset(Context::FUNCTION_MAP_INDEX))); | 6375 __ movq(rcx, Operand(rcx, Context::SlotOffset(Context::FUNCTION_MAP_INDEX))); |
6377 __ movq(FieldOperand(rax, JSObject::kMapOffset), rcx); | 6376 __ movq(FieldOperand(rax, JSObject::kMapOffset), rcx); |
6378 | 6377 |
6379 // Clone the rest of the boilerplate fields. We don't have to update | 6378 // Initialize the rest of the function. We don't have to update the |
6380 // the write barrier because the allocated object is in new space. | 6379 // write barrier because the allocated object is in new space. |
6381 for (int offset = kPointerSize; | 6380 __ LoadRoot(rbx, Heap::kEmptyFixedArrayRootIndex); |
6382 offset < JSFunction::kSize; | 6381 __ LoadRoot(rcx, Heap::kTheHoleValueRootIndex); |
6383 offset += kPointerSize) { | 6382 __ movq(FieldOperand(rax, JSObject::kPropertiesOffset), rbx); |
6384 if (offset == JSFunction::kContextOffset) { | 6383 __ movq(FieldOperand(rax, JSObject::kElementsOffset), rbx); |
6385 __ movq(FieldOperand(rax, offset), rsi); | 6384 __ movq(FieldOperand(rax, JSFunction::kPrototypeOrInitialMapOffset), rcx); |
6386 } else { | 6385 __ movq(FieldOperand(rax, JSFunction::kSharedFunctionInfoOffset), rdx); |
6387 __ movq(rbx, FieldOperand(rdx, offset)); | 6386 __ movq(FieldOperand(rax, JSFunction::kContextOffset), rsi); |
6388 __ movq(FieldOperand(rax, offset), rbx); | 6387 __ movq(FieldOperand(rax, JSFunction::kLiteralsOffset), rbx); |
6389 } | |
6390 } | |
6391 | 6388 |
6392 // Return and remove the on-stack parameter. | 6389 // Return and remove the on-stack parameter. |
6393 __ ret(1 * kPointerSize); | 6390 __ ret(1 * kPointerSize); |
6394 | 6391 |
6395 // Create a new closure through the slower runtime call. | 6392 // Create a new closure through the slower runtime call. |
6396 __ bind(&gc); | 6393 __ bind(&gc); |
6397 __ pop(rcx); // Temporarily remove return address. | 6394 __ pop(rcx); // Temporarily remove return address. |
6398 __ pop(rdx); | 6395 __ pop(rdx); |
6399 __ push(rsi); | 6396 __ push(rsi); |
6400 __ push(rdx); | 6397 __ push(rdx); |
(...skipping 3589 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
9990 // Call the function from C++. | 9987 // Call the function from C++. |
9991 return FUNCTION_CAST<ModuloFunction>(buffer); | 9988 return FUNCTION_CAST<ModuloFunction>(buffer); |
9992 } | 9989 } |
9993 | 9990 |
9994 #endif | 9991 #endif |
9995 | 9992 |
9996 | 9993 |
9997 #undef __ | 9994 #undef __ |
9998 | 9995 |
9999 } } // namespace v8::internal | 9996 } } // namespace v8::internal |
OLD | NEW |