OLD | NEW |
1 // Copyright 2012 the V8 project authors. All rights reserved. | 1 // Copyright 2012 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 374 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
385 Register name, | 385 Register name, |
386 Handle<JSObject> holder_obj, | 386 Handle<JSObject> holder_obj, |
387 IC::UtilityId id) { | 387 IC::UtilityId id) { |
388 PushInterceptorArguments(masm, receiver, holder, name, holder_obj); | 388 PushInterceptorArguments(masm, receiver, holder, name, holder_obj); |
389 __ CallExternalReference( | 389 __ CallExternalReference( |
390 ExternalReference(IC_Utility(id), masm->isolate()), | 390 ExternalReference(IC_Utility(id), masm->isolate()), |
391 StubCache::kInterceptorArgsLength); | 391 StubCache::kInterceptorArgsLength); |
392 } | 392 } |
393 | 393 |
394 | 394 |
395 static void GenerateFastApiCallBody(MacroAssembler* masm, | 395 // Generate call to api function. |
396 const CallOptimization& optimization, | 396 static void GenerateFastApiCall(MacroAssembler* masm, |
397 int argc, | 397 const CallOptimization& optimization, |
398 Register holder_in, | 398 Handle<Map> receiver_map, |
399 bool restore_context) { | 399 Register receiver, |
| 400 Register scratch_in, |
| 401 int argc, |
| 402 Register* values) { |
400 ASSERT(optimization.is_simple_api_call()); | 403 ASSERT(optimization.is_simple_api_call()); |
401 | 404 |
| 405 __ PopReturnAddressTo(scratch_in); |
| 406 // receiver |
| 407 __ push(receiver); |
| 408 // Write the arguments to stack frame. |
| 409 for (int i = 0; i < argc; i++) { |
| 410 Register arg = values[argc-1-i]; |
| 411 ASSERT(!receiver.is(arg)); |
| 412 ASSERT(!scratch_in.is(arg)); |
| 413 __ push(arg); |
| 414 } |
| 415 __ PushReturnAddressFrom(scratch_in); |
| 416 // Stack now matches JSFunction abi. |
| 417 |
402 // Abi for CallApiFunctionStub. | 418 // Abi for CallApiFunctionStub. |
403 Register callee = rax; | 419 Register callee = rax; |
404 Register call_data = rbx; | 420 Register call_data = rbx; |
405 Register holder = rcx; | 421 Register holder = rcx; |
406 Register api_function_address = rdx; | 422 Register api_function_address = rdx; |
| 423 Register scratch = rdi; // scratch_in is no longer valid. |
407 | 424 |
408 // Put holder in place. | 425 // Put holder in place. |
409 __ Move(holder, holder_in); | 426 CallOptimization::HolderLookup holder_lookup; |
410 | 427 Handle<JSObject> api_holder = optimization.LookupHolderOfExpectedType( |
411 Register scratch = rdi; | 428 receiver_map, |
| 429 &holder_lookup); |
| 430 switch (holder_lookup) { |
| 431 case CallOptimization::kHolderIsReceiver: |
| 432 __ Move(holder, receiver); |
| 433 break; |
| 434 case CallOptimization::kHolderFound: |
| 435 __ Move(holder, api_holder); |
| 436 break; |
| 437 case CallOptimization::kHolderNotFound: |
| 438 UNREACHABLE(); |
| 439 break; |
| 440 } |
412 | 441 |
413 Isolate* isolate = masm->isolate(); | 442 Isolate* isolate = masm->isolate(); |
414 Handle<JSFunction> function = optimization.constant_function(); | 443 Handle<JSFunction> function = optimization.constant_function(); |
415 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); | 444 Handle<CallHandlerInfo> api_call_info = optimization.api_call_info(); |
416 Handle<Object> call_data_obj(api_call_info->data(), isolate); | 445 Handle<Object> call_data_obj(api_call_info->data(), isolate); |
417 | 446 |
418 // Put callee in place. | 447 // Put callee in place. |
419 __ Move(callee, function); | 448 __ Move(callee, function); |
420 | 449 |
421 bool call_data_undefined = false; | 450 bool call_data_undefined = false; |
422 // Put call_data in place. | 451 // Put call_data in place. |
423 if (isolate->heap()->InNewSpace(*call_data_obj)) { | 452 if (isolate->heap()->InNewSpace(*call_data_obj)) { |
424 __ Move(scratch, api_call_info); | 453 __ Move(scratch, api_call_info); |
425 __ movp(call_data, FieldOperand(scratch, CallHandlerInfo::kDataOffset)); | 454 __ movp(call_data, FieldOperand(scratch, CallHandlerInfo::kDataOffset)); |
426 } else if (call_data_obj->IsUndefined()) { | 455 } else if (call_data_obj->IsUndefined()) { |
427 call_data_undefined = true; | 456 call_data_undefined = true; |
428 __ LoadRoot(call_data, Heap::kUndefinedValueRootIndex); | 457 __ LoadRoot(call_data, Heap::kUndefinedValueRootIndex); |
429 } else { | 458 } else { |
430 __ Move(call_data, call_data_obj); | 459 __ Move(call_data, call_data_obj); |
431 } | 460 } |
432 | 461 |
433 // Put api_function_address in place. | 462 // Put api_function_address in place. |
434 Address function_address = v8::ToCData<Address>(api_call_info->callback()); | 463 Address function_address = v8::ToCData<Address>(api_call_info->callback()); |
435 __ Move( | 464 __ Move( |
436 api_function_address, function_address, RelocInfo::EXTERNAL_REFERENCE); | 465 api_function_address, function_address, RelocInfo::EXTERNAL_REFERENCE); |
437 | 466 |
438 // Jump to stub. | 467 // Jump to stub. |
439 CallApiFunctionStub stub(restore_context, call_data_undefined, argc); | 468 CallApiFunctionStub stub(true, call_data_undefined, argc); |
440 __ TailCallStub(&stub); | 469 __ TailCallStub(&stub); |
441 } | 470 } |
442 | 471 |
443 | 472 |
444 // Generate call to api function. | |
445 static void GenerateFastApiCall(MacroAssembler* masm, | |
446 const CallOptimization& optimization, | |
447 Register receiver, | |
448 Register scratch1, | |
449 int argc, | |
450 Register* values) { | |
451 __ PopReturnAddressTo(scratch1); | |
452 // receiver | |
453 __ push(receiver); | |
454 // Write the arguments to stack frame. | |
455 for (int i = 0; i < argc; i++) { | |
456 Register arg = values[argc-1-i]; | |
457 ASSERT(!receiver.is(arg)); | |
458 ASSERT(!scratch1.is(arg)); | |
459 __ push(arg); | |
460 } | |
461 __ PushReturnAddressFrom(scratch1); | |
462 // Stack now matches JSFunction abi. | |
463 GenerateFastApiCallBody(masm, | |
464 optimization, | |
465 argc, | |
466 receiver, | |
467 true); | |
468 } | |
469 | |
470 | |
471 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, | 473 void StoreStubCompiler::GenerateRestoreName(MacroAssembler* masm, |
472 Label* label, | 474 Label* label, |
473 Handle<Name> name) { | 475 Handle<Name> name) { |
474 if (!label->is_unused()) { | 476 if (!label->is_unused()) { |
475 __ bind(label); | 477 __ bind(label); |
476 __ Move(this->name(), name); | 478 __ Move(this->name(), name); |
477 } | 479 } |
478 } | 480 } |
479 | 481 |
480 | 482 |
(...skipping 480 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
961 } else { | 963 } else { |
962 KeyedLoadFieldStub stub(field.is_inobject(holder), | 964 KeyedLoadFieldStub stub(field.is_inobject(holder), |
963 field.translate(holder), | 965 field.translate(holder), |
964 representation); | 966 representation); |
965 GenerateTailCall(masm(), stub.GetCode(isolate())); | 967 GenerateTailCall(masm(), stub.GetCode(isolate())); |
966 } | 968 } |
967 } | 969 } |
968 | 970 |
969 | 971 |
970 void LoadStubCompiler::GenerateLoadCallback( | 972 void LoadStubCompiler::GenerateLoadCallback( |
971 const CallOptimization& call_optimization) { | 973 const CallOptimization& call_optimization, |
| 974 Handle<Map> receiver_map) { |
972 GenerateFastApiCall( | 975 GenerateFastApiCall( |
973 masm(), call_optimization, receiver(), | 976 masm(), call_optimization, receiver_map, |
974 scratch1(), 0, NULL); | 977 receiver(), scratch1(), 0, NULL); |
975 } | 978 } |
976 | 979 |
977 | 980 |
978 void LoadStubCompiler::GenerateLoadCallback( | 981 void LoadStubCompiler::GenerateLoadCallback( |
979 Register reg, | 982 Register reg, |
980 Handle<ExecutableAccessorInfo> callback) { | 983 Handle<ExecutableAccessorInfo> callback) { |
981 // Insert additional parameters into the stack frame above return address. | 984 // Insert additional parameters into the stack frame above return address. |
982 ASSERT(!scratch4().is(reg)); | 985 ASSERT(!scratch4().is(reg)); |
983 __ PopReturnAddressTo(scratch4()); | 986 __ PopReturnAddressTo(scratch4()); |
984 | 987 |
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1158 Handle<Code> StoreStubCompiler::CompileStoreCallback( | 1161 Handle<Code> StoreStubCompiler::CompileStoreCallback( |
1159 Handle<JSObject> object, | 1162 Handle<JSObject> object, |
1160 Handle<JSObject> holder, | 1163 Handle<JSObject> holder, |
1161 Handle<Name> name, | 1164 Handle<Name> name, |
1162 const CallOptimization& call_optimization) { | 1165 const CallOptimization& call_optimization) { |
1163 HandlerFrontend(IC::CurrentTypeOf(object, isolate()), | 1166 HandlerFrontend(IC::CurrentTypeOf(object, isolate()), |
1164 receiver(), holder, name); | 1167 receiver(), holder, name); |
1165 | 1168 |
1166 Register values[] = { value() }; | 1169 Register values[] = { value() }; |
1167 GenerateFastApiCall( | 1170 GenerateFastApiCall( |
1168 masm(), call_optimization, receiver(), | 1171 masm(), call_optimization, handle(object->map()), |
1169 scratch1(), 1, values); | 1172 receiver(), scratch1(), 1, values); |
1170 | 1173 |
1171 // Return the generated code. | 1174 // Return the generated code. |
1172 return GetCode(kind(), Code::FAST, name); | 1175 return GetCode(kind(), Code::FAST, name); |
1173 } | 1176 } |
1174 | 1177 |
1175 | 1178 |
1176 #undef __ | 1179 #undef __ |
1177 #define __ ACCESS_MASM(masm) | 1180 #define __ ACCESS_MASM(masm) |
1178 | 1181 |
1179 | 1182 |
(...skipping 305 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1485 // ----------------------------------- | 1488 // ----------------------------------- |
1486 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); | 1489 TailCallBuiltin(masm, Builtins::kKeyedLoadIC_Miss); |
1487 } | 1490 } |
1488 | 1491 |
1489 | 1492 |
1490 #undef __ | 1493 #undef __ |
1491 | 1494 |
1492 } } // namespace v8::internal | 1495 } } // namespace v8::internal |
1493 | 1496 |
1494 #endif // V8_TARGET_ARCH_X64 | 1497 #endif // V8_TARGET_ARCH_X64 |
OLD | NEW |