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

Side by Side Diff: src/ia32/stub-cache-ia32.cc

Issue 6696107: Cleanup more isolate usage in ia32 files. (Closed) Base URL: https://v8.googlecode.com/svn/branches/bleeding_edge
Patch Set: Address comments. Created 9 years, 9 months 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/ia32/macro-assembler-ia32.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 257 matching lines...) Expand 10 before | Expand all | Expand 10 after
268 Register prototype) { 268 Register prototype) {
269 __ LoadGlobalFunction(index, prototype); 269 __ LoadGlobalFunction(index, prototype);
270 __ LoadGlobalFunctionInitialMap(prototype, prototype); 270 __ LoadGlobalFunctionInitialMap(prototype, prototype);
271 // Load the prototype from the initial map. 271 // Load the prototype from the initial map.
272 __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); 272 __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset));
273 } 273 }
274 274
275 275
276 void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype( 276 void StubCompiler::GenerateDirectLoadGlobalFunctionPrototype(
277 MacroAssembler* masm, int index, Register prototype, Label* miss) { 277 MacroAssembler* masm, int index, Register prototype, Label* miss) {
278 Isolate* isolate = masm->isolate();
279 // Check we're still in the same context. 278 // Check we're still in the same context.
280 __ cmp(Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)), 279 __ cmp(Operand(esi, Context::SlotOffset(Context::GLOBAL_INDEX)),
281 isolate->global()); 280 masm->isolate()->global());
282 __ j(not_equal, miss); 281 __ j(not_equal, miss);
283 // Get the global function with the given index. 282 // Get the global function with the given index.
284 JSFunction* function = 283 JSFunction* function =
285 JSFunction::cast(isolate->global_context()->get(index)); 284 JSFunction::cast(masm->isolate()->global_context()->get(index));
286 // Load its initial map. The global functions all have initial maps. 285 // Load its initial map. The global functions all have initial maps.
287 __ Set(prototype, Immediate(Handle<Map>(function->initial_map()))); 286 __ Set(prototype, Immediate(Handle<Map>(function->initial_map())));
288 // Load the prototype from the initial map. 287 // Load the prototype from the initial map.
289 __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset)); 288 __ mov(prototype, FieldOperand(prototype, Map::kPrototypeOffset));
290 } 289 }
291 290
292 291
293 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm, 292 void StubCompiler::GenerateLoadArrayLength(MacroAssembler* masm,
294 Register receiver, 293 Register receiver,
295 Register scratch, 294 Register scratch,
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after
393 } 392 }
394 393
395 394
396 static void PushInterceptorArguments(MacroAssembler* masm, 395 static void PushInterceptorArguments(MacroAssembler* masm,
397 Register receiver, 396 Register receiver,
398 Register holder, 397 Register holder,
399 Register name, 398 Register name,
400 JSObject* holder_obj) { 399 JSObject* holder_obj) {
401 __ push(name); 400 __ push(name);
402 InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor(); 401 InterceptorInfo* interceptor = holder_obj->GetNamedInterceptor();
403 ASSERT(!HEAP->InNewSpace(interceptor)); 402 ASSERT(!masm->isolate()->heap()->InNewSpace(interceptor));
404 Register scratch = name; 403 Register scratch = name;
405 __ mov(scratch, Immediate(Handle<Object>(interceptor))); 404 __ mov(scratch, Immediate(Handle<Object>(interceptor)));
406 __ push(scratch); 405 __ push(scratch);
407 __ push(receiver); 406 __ push(receiver);
408 __ push(holder); 407 __ push(holder);
409 __ push(FieldOperand(scratch, InterceptorInfo::kDataOffset)); 408 __ push(FieldOperand(scratch, InterceptorInfo::kDataOffset));
410 } 409 }
411 410
412 411
413 static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm, 412 static void CompileCallLoadPropertyWithInterceptor(MacroAssembler* masm,
(...skipping 65 matching lines...) Expand 10 before | Expand all | Expand 10 after
479 // ----------------------------------- 478 // -----------------------------------
480 // Get the function and setup the context. 479 // Get the function and setup the context.
481 JSFunction* function = optimization.constant_function(); 480 JSFunction* function = optimization.constant_function();
482 __ mov(edi, Immediate(Handle<JSFunction>(function))); 481 __ mov(edi, Immediate(Handle<JSFunction>(function)));
483 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); 482 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
484 483
485 // Pass the additional arguments. 484 // Pass the additional arguments.
486 __ mov(Operand(esp, 2 * kPointerSize), edi); 485 __ mov(Operand(esp, 2 * kPointerSize), edi);
487 Object* call_data = optimization.api_call_info()->data(); 486 Object* call_data = optimization.api_call_info()->data();
488 Handle<CallHandlerInfo> api_call_info_handle(optimization.api_call_info()); 487 Handle<CallHandlerInfo> api_call_info_handle(optimization.api_call_info());
489 if (HEAP->InNewSpace(call_data)) { 488 if (masm->isolate()->heap()->InNewSpace(call_data)) {
490 __ mov(ecx, api_call_info_handle); 489 __ mov(ecx, api_call_info_handle);
491 __ mov(ebx, FieldOperand(ecx, CallHandlerInfo::kDataOffset)); 490 __ mov(ebx, FieldOperand(ecx, CallHandlerInfo::kDataOffset));
492 __ mov(Operand(esp, 3 * kPointerSize), ebx); 491 __ mov(Operand(esp, 3 * kPointerSize), ebx);
493 } else { 492 } else {
494 __ mov(Operand(esp, 3 * kPointerSize), 493 __ mov(Operand(esp, 3 * kPointerSize),
495 Immediate(Handle<Object>(call_data))); 494 Immediate(Handle<Object>(call_data)));
496 } 495 }
497 496
498 // Prepare arguments. 497 // Prepare arguments.
499 __ lea(eax, Operand(esp, 3 * kPointerSize)); 498 __ lea(eax, Operand(esp, 3 * kPointerSize));
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
573 } else { 572 } else {
574 CompileRegular(masm, 573 CompileRegular(masm,
575 object, 574 object,
576 receiver, 575 receiver,
577 scratch1, 576 scratch1,
578 scratch2, 577 scratch2,
579 scratch3, 578 scratch3,
580 name, 579 name,
581 holder, 580 holder,
582 miss); 581 miss);
583 return HEAP->undefined_value(); // Success. 582 return masm->isolate()->heap()->undefined_value(); // Success.
584 } 583 }
585 } 584 }
586 585
587 private: 586 private:
588 MaybeObject* CompileCacheable(MacroAssembler* masm, 587 MaybeObject* CompileCacheable(MacroAssembler* masm,
589 JSObject* object, 588 JSObject* object,
590 Register receiver, 589 Register receiver,
591 Register scratch1, 590 Register scratch1,
592 Register scratch2, 591 Register scratch2,
593 Register scratch3, 592 Register scratch3,
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after
672 FreeSpaceForFastApiCall(masm, scratch1); 671 FreeSpaceForFastApiCall(masm, scratch1);
673 __ jmp(miss_label); 672 __ jmp(miss_label);
674 } 673 }
675 674
676 // Invoke a regular function. 675 // Invoke a regular function.
677 __ bind(&regular_invoke); 676 __ bind(&regular_invoke);
678 if (can_do_fast_api_call) { 677 if (can_do_fast_api_call) {
679 FreeSpaceForFastApiCall(masm, scratch1); 678 FreeSpaceForFastApiCall(masm, scratch1);
680 } 679 }
681 680
682 return HEAP->undefined_value(); // Success. 681 return masm->isolate()->heap()->undefined_value(); // Success.
683 } 682 }
684 683
685 void CompileRegular(MacroAssembler* masm, 684 void CompileRegular(MacroAssembler* masm,
686 JSObject* object, 685 JSObject* object,
687 Register receiver, 686 Register receiver,
688 Register scratch1, 687 Register scratch1,
689 Register scratch2, 688 Register scratch2,
690 Register scratch3, 689 Register scratch3,
691 String* name, 690 String* name,
692 JSObject* interceptor_holder, 691 JSObject* interceptor_holder,
(...skipping 216 matching lines...) Expand 10 before | Expand all | Expand 10 after
909 Register holder_reg, 908 Register holder_reg,
910 Register scratch1, 909 Register scratch1,
911 Register scratch2, 910 Register scratch2,
912 String* name, 911 String* name,
913 int save_at_depth, 912 int save_at_depth,
914 Label* miss) { 913 Label* miss) {
915 // Make sure there's no overlap between holder and object registers. 914 // Make sure there's no overlap between holder and object registers.
916 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg)); 915 ASSERT(!scratch1.is(object_reg) && !scratch1.is(holder_reg));
917 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg) 916 ASSERT(!scratch2.is(object_reg) && !scratch2.is(holder_reg)
918 && !scratch2.is(scratch1)); 917 && !scratch2.is(scratch1));
918
919 Heap* heap = isolate()->heap();
920
919 // Keep track of the current object in register reg. 921 // Keep track of the current object in register reg.
920 Register reg = object_reg; 922 Register reg = object_reg;
921 JSObject* current = object; 923 JSObject* current = object;
922 int depth = 0; 924 int depth = 0;
923 925
924 if (save_at_depth == depth) { 926 if (save_at_depth == depth) {
925 __ mov(Operand(esp, kPointerSize), reg); 927 __ mov(Operand(esp, kPointerSize), reg);
926 } 928 }
927 929
928 // Traverse the prototype chain and check the maps in the prototype chain for 930 // Traverse the prototype chain and check the maps in the prototype chain for
929 // fast and global objects or do negative lookup for normal objects. 931 // fast and global objects or do negative lookup for normal objects.
930 while (current != holder) { 932 while (current != holder) {
931 depth++; 933 depth++;
932 934
933 // Only global objects and objects that do not require access 935 // Only global objects and objects that do not require access
934 // checks are allowed in stubs. 936 // checks are allowed in stubs.
935 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded()); 937 ASSERT(current->IsJSGlobalProxy() || !current->IsAccessCheckNeeded());
936 938
937 ASSERT(current->GetPrototype()->IsJSObject()); 939 ASSERT(current->GetPrototype()->IsJSObject());
938 JSObject* prototype = JSObject::cast(current->GetPrototype()); 940 JSObject* prototype = JSObject::cast(current->GetPrototype());
939 if (!current->HasFastProperties() && 941 if (!current->HasFastProperties() &&
940 !current->IsJSGlobalObject() && 942 !current->IsJSGlobalObject() &&
941 !current->IsJSGlobalProxy()) { 943 !current->IsJSGlobalProxy()) {
942 if (!name->IsSymbol()) { 944 if (!name->IsSymbol()) {
943 MaybeObject* maybe_lookup_result = HEAP->LookupSymbol(name); 945 MaybeObject* maybe_lookup_result = heap->LookupSymbol(name);
944 Object* lookup_result = NULL; // Initialization to please compiler. 946 Object* lookup_result = NULL; // Initialization to please compiler.
945 if (!maybe_lookup_result->ToObject(&lookup_result)) { 947 if (!maybe_lookup_result->ToObject(&lookup_result)) {
946 set_failure(Failure::cast(maybe_lookup_result)); 948 set_failure(Failure::cast(maybe_lookup_result));
947 return reg; 949 return reg;
948 } 950 }
949 name = String::cast(lookup_result); 951 name = String::cast(lookup_result);
950 } 952 }
951 ASSERT(current->property_dictionary()->FindEntry(name) == 953 ASSERT(current->property_dictionary()->FindEntry(name) ==
952 StringDictionary::kNotFound); 954 StringDictionary::kNotFound);
953 955
954 GenerateDictionaryNegativeLookup(masm(), 956 GenerateDictionaryNegativeLookup(masm(),
955 miss, 957 miss,
956 reg, 958 reg,
957 name, 959 name,
958 scratch1, 960 scratch1,
959 scratch2); 961 scratch2);
960 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); 962 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
961 reg = holder_reg; // from now the object is in holder_reg 963 reg = holder_reg; // from now the object is in holder_reg
962 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset)); 964 __ mov(reg, FieldOperand(scratch1, Map::kPrototypeOffset));
963 } else if (HEAP->InNewSpace(prototype)) { 965 } else if (heap->InNewSpace(prototype)) {
964 // Get the map of the current object. 966 // Get the map of the current object.
965 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset)); 967 __ mov(scratch1, FieldOperand(reg, HeapObject::kMapOffset));
966 __ cmp(Operand(scratch1), Immediate(Handle<Map>(current->map()))); 968 __ cmp(Operand(scratch1), Immediate(Handle<Map>(current->map())));
967 // Branch on the result of the map check. 969 // Branch on the result of the map check.
968 __ j(not_equal, miss, not_taken); 970 __ j(not_equal, miss, not_taken);
969 // Check access rights to the global object. This has to happen 971 // Check access rights to the global object. This has to happen
970 // after the map check so that we know that the object is 972 // after the map check so that we know that the object is
971 // actually a global object. 973 // actually a global object.
972 if (current->IsJSGlobalProxy()) { 974 if (current->IsJSGlobalProxy()) {
973 __ CheckAccessGlobalProxy(reg, scratch1, miss); 975 __ CheckAccessGlobalProxy(reg, scratch1, miss);
(...skipping 109 matching lines...) Expand 10 before | Expand all | Expand 10 after
1083 1085
1084 // Insert additional parameters into the stack frame above return address. 1086 // Insert additional parameters into the stack frame above return address.
1085 ASSERT(!scratch3.is(reg)); 1087 ASSERT(!scratch3.is(reg));
1086 __ pop(scratch3); // Get return address to place it below. 1088 __ pop(scratch3); // Get return address to place it below.
1087 1089
1088 __ push(receiver); // receiver 1090 __ push(receiver); // receiver
1089 __ mov(scratch2, Operand(esp)); 1091 __ mov(scratch2, Operand(esp));
1090 ASSERT(!scratch2.is(reg)); 1092 ASSERT(!scratch2.is(reg));
1091 __ push(reg); // holder 1093 __ push(reg); // holder
1092 // Push data from AccessorInfo. 1094 // Push data from AccessorInfo.
1093 if (HEAP->InNewSpace(callback_handle->data())) { 1095 if (isolate()->heap()->InNewSpace(callback_handle->data())) {
1094 __ mov(scratch1, Immediate(callback_handle)); 1096 __ mov(scratch1, Immediate(callback_handle));
1095 __ push(FieldOperand(scratch1, AccessorInfo::kDataOffset)); 1097 __ push(FieldOperand(scratch1, AccessorInfo::kDataOffset));
1096 } else { 1098 } else {
1097 __ push(Immediate(Handle<Object>(callback_handle->data()))); 1099 __ push(Immediate(Handle<Object>(callback_handle->data())));
1098 } 1100 }
1099 1101
1100 // Save a pointer to where we pushed the arguments pointer. 1102 // Save a pointer to where we pushed the arguments pointer.
1101 // This will be passed as the const AccessorInfo& to the C++ callback. 1103 // This will be passed as the const AccessorInfo& to the C++ callback.
1102 __ push(scratch2); 1104 __ push(scratch2);
1103 1105
(...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after
1279 Register holder_reg = 1281 Register holder_reg =
1280 CheckPrototypes(object, receiver, interceptor_holder, 1282 CheckPrototypes(object, receiver, interceptor_holder,
1281 scratch1, scratch2, scratch3, name, miss); 1283 scratch1, scratch2, scratch3, name, miss);
1282 __ pop(scratch2); // save old return address 1284 __ pop(scratch2); // save old return address
1283 PushInterceptorArguments(masm(), receiver, holder_reg, 1285 PushInterceptorArguments(masm(), receiver, holder_reg,
1284 name_reg, interceptor_holder); 1286 name_reg, interceptor_holder);
1285 __ push(scratch2); // restore old return address 1287 __ push(scratch2); // restore old return address
1286 1288
1287 ExternalReference ref = 1289 ExternalReference ref =
1288 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad), 1290 ExternalReference(IC_Utility(IC::kLoadPropertyWithInterceptorForLoad),
1289 masm()->isolate()); 1291 isolate());
1290 __ TailCallExternalReference(ref, 5, 1); 1292 __ TailCallExternalReference(ref, 5, 1);
1291 } 1293 }
1292 } 1294 }
1293 1295
1294 1296
1295 void CallStubCompiler::GenerateNameCheck(String* name, Label* miss) { 1297 void CallStubCompiler::GenerateNameCheck(String* name, Label* miss) {
1296 if (kind_ == Code::KEYED_CALL_IC) { 1298 if (kind_ == Code::KEYED_CALL_IC) {
1297 __ cmp(Operand(ecx), Immediate(Handle<String>(name))); 1299 __ cmp(Operand(ecx), Immediate(Handle<String>(name)));
1298 __ j(not_equal, miss, not_taken); 1300 __ j(not_equal, miss, not_taken);
1299 } 1301 }
(...skipping 30 matching lines...) Expand all
1330 Label* miss) { 1332 Label* miss) {
1331 // Get the value from the cell. 1333 // Get the value from the cell.
1332 if (Serializer::enabled()) { 1334 if (Serializer::enabled()) {
1333 __ mov(edi, Immediate(Handle<JSGlobalPropertyCell>(cell))); 1335 __ mov(edi, Immediate(Handle<JSGlobalPropertyCell>(cell)));
1334 __ mov(edi, FieldOperand(edi, JSGlobalPropertyCell::kValueOffset)); 1336 __ mov(edi, FieldOperand(edi, JSGlobalPropertyCell::kValueOffset));
1335 } else { 1337 } else {
1336 __ mov(edi, Operand::Cell(Handle<JSGlobalPropertyCell>(cell))); 1338 __ mov(edi, Operand::Cell(Handle<JSGlobalPropertyCell>(cell)));
1337 } 1339 }
1338 1340
1339 // Check that the cell contains the same function. 1341 // Check that the cell contains the same function.
1340 if (HEAP->InNewSpace(function)) { 1342 if (isolate()->heap()->InNewSpace(function)) {
1341 // We can't embed a pointer to a function in new space so we have 1343 // We can't embed a pointer to a function in new space so we have
1342 // to verify that the shared function info is unchanged. This has 1344 // to verify that the shared function info is unchanged. This has
1343 // the nice side effect that multiple closures based on the same 1345 // the nice side effect that multiple closures based on the same
1344 // function can all use this call IC. Before we load through the 1346 // function can all use this call IC. Before we load through the
1345 // function, we have to verify that it still is a function. 1347 // function, we have to verify that it still is a function.
1346 __ test(edi, Immediate(kSmiTagMask)); 1348 __ test(edi, Immediate(kSmiTagMask));
1347 __ j(zero, miss, not_taken); 1349 __ j(zero, miss, not_taken);
1348 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx); 1350 __ CmpObjectType(edi, JS_FUNCTION_TYPE, ebx);
1349 __ j(not_equal, miss, not_taken); 1351 __ j(not_equal, miss, not_taken);
1350 1352
1351 // Check the shared function info. Make sure it hasn't changed. 1353 // Check the shared function info. Make sure it hasn't changed.
1352 __ cmp(FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset), 1354 __ cmp(FieldOperand(edi, JSFunction::kSharedFunctionInfoOffset),
1353 Immediate(Handle<SharedFunctionInfo>(function->shared()))); 1355 Immediate(Handle<SharedFunctionInfo>(function->shared())));
1354 __ j(not_equal, miss, not_taken); 1356 __ j(not_equal, miss, not_taken);
1355 } else { 1357 } else {
1356 __ cmp(Operand(edi), Immediate(Handle<JSFunction>(function))); 1358 __ cmp(Operand(edi), Immediate(Handle<JSFunction>(function)));
1357 __ j(not_equal, miss, not_taken); 1359 __ j(not_equal, miss, not_taken);
1358 } 1360 }
1359 } 1361 }
1360 1362
1361 1363
1362 MaybeObject* CallStubCompiler::GenerateMissBranch() { 1364 MaybeObject* CallStubCompiler::GenerateMissBranch() {
1363 MaybeObject* maybe_obj = 1365 MaybeObject* maybe_obj =
1364 masm()->isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(), 1366 isolate()->stub_cache()->ComputeCallMiss(arguments().immediate(),
1365 kind_); 1367 kind_);
1366 Object* obj; 1368 Object* obj;
1367 if (!maybe_obj->ToObject(&obj)) return maybe_obj; 1369 if (!maybe_obj->ToObject(&obj)) return maybe_obj;
1368 __ jmp(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET); 1370 __ jmp(Handle<Code>(Code::cast(obj)), RelocInfo::CODE_TARGET);
1369 return obj; 1371 return obj;
1370 } 1372 }
1371 1373
1372 1374
1373 MUST_USE_RESULT MaybeObject* CallStubCompiler::CompileCallField( 1375 MUST_USE_RESULT MaybeObject* CallStubCompiler::CompileCallField(
1374 JSObject* object, 1376 JSObject* object,
(...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after
1433 String* name) { 1435 String* name) {
1434 // ----------- S t a t e ------------- 1436 // ----------- S t a t e -------------
1435 // -- ecx : name 1437 // -- ecx : name
1436 // -- esp[0] : return address 1438 // -- esp[0] : return address
1437 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1439 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1438 // -- ... 1440 // -- ...
1439 // -- esp[(argc + 1) * 4] : receiver 1441 // -- esp[(argc + 1) * 4] : receiver
1440 // ----------------------------------- 1442 // -----------------------------------
1441 1443
1442 // If object is not an array, bail out to regular call. 1444 // If object is not an array, bail out to regular call.
1443 if (!object->IsJSArray() || cell != NULL) return HEAP->undefined_value(); 1445 if (!object->IsJSArray() || cell != NULL) {
1446 return isolate()->heap()->undefined_value();
1447 }
1444 1448
1445 Label miss; 1449 Label miss;
1446 1450
1447 GenerateNameCheck(name, &miss); 1451 GenerateNameCheck(name, &miss);
1448 1452
1449 // Get the receiver from the stack. 1453 // Get the receiver from the stack.
1450 const int argc = arguments().immediate(); 1454 const int argc = arguments().immediate();
1451 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1455 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1452 1456
1453 // Check that the receiver isn't a smi. 1457 // Check that the receiver isn't a smi.
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after
1511 __ InNewSpace(ebx, ecx, equal, &exit); 1515 __ InNewSpace(ebx, ecx, equal, &exit);
1512 1516
1513 __ RecordWriteHelper(ebx, edx, ecx); 1517 __ RecordWriteHelper(ebx, edx, ecx);
1514 __ ret((argc + 1) * kPointerSize); 1518 __ ret((argc + 1) * kPointerSize);
1515 1519
1516 __ bind(&attempt_to_grow_elements); 1520 __ bind(&attempt_to_grow_elements);
1517 if (!FLAG_inline_new) { 1521 if (!FLAG_inline_new) {
1518 __ jmp(&call_builtin); 1522 __ jmp(&call_builtin);
1519 } 1523 }
1520 1524
1521 Isolate* isolate = masm()->isolate();
1522 ExternalReference new_space_allocation_top = 1525 ExternalReference new_space_allocation_top =
1523 ExternalReference::new_space_allocation_top_address(isolate); 1526 ExternalReference::new_space_allocation_top_address(isolate());
1524 ExternalReference new_space_allocation_limit = 1527 ExternalReference new_space_allocation_limit =
1525 ExternalReference::new_space_allocation_limit_address(isolate); 1528 ExternalReference::new_space_allocation_limit_address(isolate());
1526 1529
1527 const int kAllocationDelta = 4; 1530 const int kAllocationDelta = 4;
1528 // Load top. 1531 // Load top.
1529 __ mov(ecx, Operand::StaticVariable(new_space_allocation_top)); 1532 __ mov(ecx, Operand::StaticVariable(new_space_allocation_top));
1530 1533
1531 // Check if it's the end of elements. 1534 // Check if it's the end of elements.
1532 __ lea(edx, FieldOperand(ebx, 1535 __ lea(edx, FieldOperand(ebx,
1533 eax, times_half_pointer_size, 1536 eax, times_half_pointer_size,
1534 FixedArray::kHeaderSize - argc * kPointerSize)); 1537 FixedArray::kHeaderSize - argc * kPointerSize));
1535 __ cmp(edx, Operand(ecx)); 1538 __ cmp(edx, Operand(ecx));
(...skipping 21 matching lines...) Expand all
1557 __ add(FieldOperand(ebx, FixedArray::kLengthOffset), 1560 __ add(FieldOperand(ebx, FixedArray::kLengthOffset),
1558 Immediate(Smi::FromInt(kAllocationDelta))); 1561 Immediate(Smi::FromInt(kAllocationDelta)));
1559 __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax); 1562 __ mov(FieldOperand(edx, JSArray::kLengthOffset), eax);
1560 1563
1561 // Elements are in new space, so write barrier is not required. 1564 // Elements are in new space, so write barrier is not required.
1562 __ ret((argc + 1) * kPointerSize); 1565 __ ret((argc + 1) * kPointerSize);
1563 } 1566 }
1564 1567
1565 __ bind(&call_builtin); 1568 __ bind(&call_builtin);
1566 __ TailCallExternalReference( 1569 __ TailCallExternalReference(
1567 ExternalReference(Builtins::c_ArrayPush, masm()->isolate()), 1570 ExternalReference(Builtins::c_ArrayPush, isolate()),
1568 argc + 1, 1571 argc + 1,
1569 1); 1572 1);
1570 } 1573 }
1571 1574
1572 __ bind(&miss); 1575 __ bind(&miss);
1573 MaybeObject* maybe_result = GenerateMissBranch(); 1576 MaybeObject* maybe_result = GenerateMissBranch();
1574 if (maybe_result->IsFailure()) return maybe_result; 1577 if (maybe_result->IsFailure()) return maybe_result;
1575 1578
1576 // Return the generated code. 1579 // Return the generated code.
1577 return GetCode(function); 1580 return GetCode(function);
1578 } 1581 }
1579 1582
1580 1583
1581 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object, 1584 MaybeObject* CallStubCompiler::CompileArrayPopCall(Object* object,
1582 JSObject* holder, 1585 JSObject* holder,
1583 JSGlobalPropertyCell* cell, 1586 JSGlobalPropertyCell* cell,
1584 JSFunction* function, 1587 JSFunction* function,
1585 String* name) { 1588 String* name) {
1586 // ----------- S t a t e ------------- 1589 // ----------- S t a t e -------------
1587 // -- ecx : name 1590 // -- ecx : name
1588 // -- esp[0] : return address 1591 // -- esp[0] : return address
1589 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1592 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1590 // -- ... 1593 // -- ...
1591 // -- esp[(argc + 1) * 4] : receiver 1594 // -- esp[(argc + 1) * 4] : receiver
1592 // ----------------------------------- 1595 // -----------------------------------
1593 1596
1594 // If object is not an array, bail out to regular call. 1597 // If object is not an array, bail out to regular call.
1595 if (!object->IsJSArray() || cell != NULL) return HEAP->undefined_value(); 1598 if (!object->IsJSArray() || cell != NULL) {
1599 return isolate()->heap()->undefined_value();
1600 }
1596 1601
1597 Label miss, return_undefined, call_builtin; 1602 Label miss, return_undefined, call_builtin;
1598 1603
1599 GenerateNameCheck(name, &miss); 1604 GenerateNameCheck(name, &miss);
1600 1605
1601 // Get the receiver from the stack. 1606 // Get the receiver from the stack.
1602 const int argc = arguments().immediate(); 1607 const int argc = arguments().immediate();
1603 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 1608 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
1604 1609
1605 // Check that the receiver isn't a smi. 1610 // Check that the receiver isn't a smi.
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
1640 FixedArray::kHeaderSize), 1645 FixedArray::kHeaderSize),
1641 Immediate(FACTORY->the_hole_value())); 1646 Immediate(FACTORY->the_hole_value()));
1642 __ ret((argc + 1) * kPointerSize); 1647 __ ret((argc + 1) * kPointerSize);
1643 1648
1644 __ bind(&return_undefined); 1649 __ bind(&return_undefined);
1645 __ mov(eax, Immediate(FACTORY->undefined_value())); 1650 __ mov(eax, Immediate(FACTORY->undefined_value()));
1646 __ ret((argc + 1) * kPointerSize); 1651 __ ret((argc + 1) * kPointerSize);
1647 1652
1648 __ bind(&call_builtin); 1653 __ bind(&call_builtin);
1649 __ TailCallExternalReference( 1654 __ TailCallExternalReference(
1650 ExternalReference(Builtins::c_ArrayPop, masm()->isolate()), 1655 ExternalReference(Builtins::c_ArrayPop, isolate()),
1651 argc + 1, 1656 argc + 1,
1652 1); 1657 1);
1653 1658
1654 __ bind(&miss); 1659 __ bind(&miss);
1655 MaybeObject* maybe_result = GenerateMissBranch(); 1660 MaybeObject* maybe_result = GenerateMissBranch();
1656 if (maybe_result->IsFailure()) return maybe_result; 1661 if (maybe_result->IsFailure()) return maybe_result;
1657 1662
1658 // Return the generated code. 1663 // Return the generated code.
1659 return GetCode(function); 1664 return GetCode(function);
1660 } 1665 }
1661 1666
1662 1667
1663 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall( 1668 MaybeObject* CallStubCompiler::CompileStringCharCodeAtCall(
1664 Object* object, 1669 Object* object,
1665 JSObject* holder, 1670 JSObject* holder,
1666 JSGlobalPropertyCell* cell, 1671 JSGlobalPropertyCell* cell,
1667 JSFunction* function, 1672 JSFunction* function,
1668 String* name) { 1673 String* name) {
1669 // ----------- S t a t e ------------- 1674 // ----------- S t a t e -------------
1670 // -- ecx : function name 1675 // -- ecx : function name
1671 // -- esp[0] : return address 1676 // -- esp[0] : return address
1672 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1677 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1673 // -- ... 1678 // -- ...
1674 // -- esp[(argc + 1) * 4] : receiver 1679 // -- esp[(argc + 1) * 4] : receiver
1675 // ----------------------------------- 1680 // -----------------------------------
1676 1681
1677 // If object is not a string, bail out to regular call. 1682 // If object is not a string, bail out to regular call.
1678 if (!object->IsString() || cell != NULL) { 1683 if (!object->IsString() || cell != NULL) {
1679 return masm()->isolate()->heap()->undefined_value(); 1684 return isolate()->heap()->undefined_value();
1680 } 1685 }
1681 1686
1682 const int argc = arguments().immediate(); 1687 const int argc = arguments().immediate();
1683 1688
1684 Label miss; 1689 Label miss;
1685 Label name_miss; 1690 Label name_miss;
1686 Label index_out_of_range; 1691 Label index_out_of_range;
1687 Label* index_out_of_range_label = &index_out_of_range; 1692 Label* index_out_of_range_label = &index_out_of_range;
1688 1693
1689 if (kind_ == Code::CALL_IC && extra_ic_state_ == DEFAULT_STRING_STUB) { 1694 if (kind_ == Code::CALL_IC && extra_ic_state_ == DEFAULT_STRING_STUB) {
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after
1752 String* name) { 1757 String* name) {
1753 // ----------- S t a t e ------------- 1758 // ----------- S t a t e -------------
1754 // -- ecx : function name 1759 // -- ecx : function name
1755 // -- esp[0] : return address 1760 // -- esp[0] : return address
1756 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1761 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1757 // -- ... 1762 // -- ...
1758 // -- esp[(argc + 1) * 4] : receiver 1763 // -- esp[(argc + 1) * 4] : receiver
1759 // ----------------------------------- 1764 // -----------------------------------
1760 1765
1761 // If object is not a string, bail out to regular call. 1766 // If object is not a string, bail out to regular call.
1762 if (!object->IsString() || cell != NULL) return HEAP->undefined_value(); 1767 if (!object->IsString() || cell != NULL) {
1768 return isolate()->heap()->undefined_value();
1769 }
1763 1770
1764 const int argc = arguments().immediate(); 1771 const int argc = arguments().immediate();
1765 1772
1766 Label miss; 1773 Label miss;
1767 Label name_miss; 1774 Label name_miss;
1768 Label index_out_of_range; 1775 Label index_out_of_range;
1769 Label* index_out_of_range_label = &index_out_of_range; 1776 Label* index_out_of_range_label = &index_out_of_range;
1770 1777
1771 if (kind_ == Code::CALL_IC && extra_ic_state_ == DEFAULT_STRING_STUB) { 1778 if (kind_ == Code::CALL_IC && extra_ic_state_ == DEFAULT_STRING_STUB) {
1772 index_out_of_range_label = &miss; 1779 index_out_of_range_label = &miss;
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
1839 // -- esp[0] : return address 1846 // -- esp[0] : return address
1840 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1847 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1841 // -- ... 1848 // -- ...
1842 // -- esp[(argc + 1) * 4] : receiver 1849 // -- esp[(argc + 1) * 4] : receiver
1843 // ----------------------------------- 1850 // -----------------------------------
1844 1851
1845 const int argc = arguments().immediate(); 1852 const int argc = arguments().immediate();
1846 1853
1847 // If the object is not a JSObject or we got an unexpected number of 1854 // If the object is not a JSObject or we got an unexpected number of
1848 // arguments, bail out to the regular call. 1855 // arguments, bail out to the regular call.
1849 if (!object->IsJSObject() || argc != 1) return HEAP->undefined_value(); 1856 if (!object->IsJSObject() || argc != 1) {
1857 return isolate()->heap()->undefined_value();
1858 }
1850 1859
1851 Label miss; 1860 Label miss;
1852 GenerateNameCheck(name, &miss); 1861 GenerateNameCheck(name, &miss);
1853 1862
1854 if (cell == NULL) { 1863 if (cell == NULL) {
1855 __ mov(edx, Operand(esp, 2 * kPointerSize)); 1864 __ mov(edx, Operand(esp, 2 * kPointerSize));
1856 1865
1857 STATIC_ASSERT(kSmiTag == 0); 1866 STATIC_ASSERT(kSmiTag == 0);
1858 __ test(edx, Immediate(kSmiTagMask)); 1867 __ test(edx, Immediate(kSmiTagMask));
1859 __ j(zero, &miss); 1868 __ j(zero, &miss);
(...skipping 47 matching lines...) Expand 10 before | Expand all | Expand 10 after
1907 JSFunction* function, 1916 JSFunction* function,
1908 String* name) { 1917 String* name) {
1909 // ----------- S t a t e ------------- 1918 // ----------- S t a t e -------------
1910 // -- ecx : name 1919 // -- ecx : name
1911 // -- esp[0] : return address 1920 // -- esp[0] : return address
1912 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 1921 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
1913 // -- ... 1922 // -- ...
1914 // -- esp[(argc + 1) * 4] : receiver 1923 // -- esp[(argc + 1) * 4] : receiver
1915 // ----------------------------------- 1924 // -----------------------------------
1916 1925
1917 if (masm()->isolate()->cpu_features()->IsSupported(SSE2)) 1926 if (isolate()->cpu_features()->IsSupported(SSE2)) {
1918 return HEAP->undefined_value(); 1927 return isolate()->heap()->undefined_value();
1928 }
1929
1919 CpuFeatures::Scope use_sse2(SSE2); 1930 CpuFeatures::Scope use_sse2(SSE2);
1920 1931
1921 const int argc = arguments().immediate(); 1932 const int argc = arguments().immediate();
1922 1933
1923 // If the object is not a JSObject or we got an unexpected number of 1934 // If the object is not a JSObject or we got an unexpected number of
1924 // arguments, bail out to the regular call. 1935 // arguments, bail out to the regular call.
1925 if (!object->IsJSObject() || argc != 1) return HEAP->undefined_value(); 1936 if (!object->IsJSObject() || argc != 1) {
1937 return isolate()->heap()->undefined_value();
1938 }
1926 1939
1927 Label miss; 1940 Label miss;
1928 GenerateNameCheck(name, &miss); 1941 GenerateNameCheck(name, &miss);
1929 1942
1930 if (cell == NULL) { 1943 if (cell == NULL) {
1931 __ mov(edx, Operand(esp, 2 * kPointerSize)); 1944 __ mov(edx, Operand(esp, 2 * kPointerSize));
1932 1945
1933 STATIC_ASSERT(kSmiTag == 0); 1946 STATIC_ASSERT(kSmiTag == 0);
1934 __ test(edx, Immediate(kSmiTagMask)); 1947 __ test(edx, Immediate(kSmiTagMask));
1935 __ j(zero, &miss); 1948 __ j(zero, &miss);
(...skipping 101 matching lines...) Expand 10 before | Expand all | Expand 10 after
2037 // -- esp[0] : return address 2050 // -- esp[0] : return address
2038 // -- esp[(argc - n) * 4] : arg[n] (zero-based) 2051 // -- esp[(argc - n) * 4] : arg[n] (zero-based)
2039 // -- ... 2052 // -- ...
2040 // -- esp[(argc + 1) * 4] : receiver 2053 // -- esp[(argc + 1) * 4] : receiver
2041 // ----------------------------------- 2054 // -----------------------------------
2042 2055
2043 const int argc = arguments().immediate(); 2056 const int argc = arguments().immediate();
2044 2057
2045 // If the object is not a JSObject or we got an unexpected number of 2058 // If the object is not a JSObject or we got an unexpected number of
2046 // arguments, bail out to the regular call. 2059 // arguments, bail out to the regular call.
2047 if (!object->IsJSObject() || argc != 1) return HEAP->undefined_value(); 2060 if (!object->IsJSObject() || argc != 1) {
2061 return isolate()->heap()->undefined_value();
2062 }
2048 2063
2049 Label miss; 2064 Label miss;
2050 GenerateNameCheck(name, &miss); 2065 GenerateNameCheck(name, &miss);
2051 2066
2052 if (cell == NULL) { 2067 if (cell == NULL) {
2053 __ mov(edx, Operand(esp, 2 * kPointerSize)); 2068 __ mov(edx, Operand(esp, 2 * kPointerSize));
2054 2069
2055 STATIC_ASSERT(kSmiTag == 0); 2070 STATIC_ASSERT(kSmiTag == 0);
2056 __ test(edx, Immediate(kSmiTagMask)); 2071 __ test(edx, Immediate(kSmiTagMask));
2057 __ j(zero, &miss); 2072 __ j(zero, &miss);
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after
2133 MaybeObject* CallStubCompiler::CompileFastApiCall( 2148 MaybeObject* CallStubCompiler::CompileFastApiCall(
2134 const CallOptimization& optimization, 2149 const CallOptimization& optimization,
2135 Object* object, 2150 Object* object,
2136 JSObject* holder, 2151 JSObject* holder,
2137 JSGlobalPropertyCell* cell, 2152 JSGlobalPropertyCell* cell,
2138 JSFunction* function, 2153 JSFunction* function,
2139 String* name) { 2154 String* name) {
2140 ASSERT(optimization.is_simple_api_call()); 2155 ASSERT(optimization.is_simple_api_call());
2141 // Bail out if object is a global object as we don't want to 2156 // Bail out if object is a global object as we don't want to
2142 // repatch it to global receiver. 2157 // repatch it to global receiver.
2143 if (object->IsGlobalObject()) return HEAP->undefined_value(); 2158 Heap* heap = isolate()->heap();
2144 if (cell != NULL) return HEAP->undefined_value(); 2159 if (object->IsGlobalObject()) return heap->undefined_value();
2160 if (cell != NULL) return heap->undefined_value();
2145 int depth = optimization.GetPrototypeDepthOfExpectedType( 2161 int depth = optimization.GetPrototypeDepthOfExpectedType(
2146 JSObject::cast(object), holder); 2162 JSObject::cast(object), holder);
2147 if (depth == kInvalidProtoDepth) return HEAP->undefined_value(); 2163 if (depth == kInvalidProtoDepth) return heap->undefined_value();
2148 2164
2149 Label miss, miss_before_stack_reserved; 2165 Label miss, miss_before_stack_reserved;
2150 2166
2151 GenerateNameCheck(name, &miss_before_stack_reserved); 2167 GenerateNameCheck(name, &miss_before_stack_reserved);
2152 2168
2153 // Get the receiver from the stack. 2169 // Get the receiver from the stack.
2154 const int argc = arguments().immediate(); 2170 const int argc = arguments().immediate();
2155 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize)); 2171 __ mov(edx, Operand(esp, (argc + 1) * kPointerSize));
2156 2172
2157 // Check that the receiver isn't a smi. 2173 // Check that the receiver isn't a smi.
2158 __ test(edx, Immediate(kSmiTagMask)); 2174 __ test(edx, Immediate(kSmiTagMask));
2159 __ j(zero, &miss_before_stack_reserved, not_taken); 2175 __ j(zero, &miss_before_stack_reserved, not_taken);
2160 2176
2161 Counters* counters = masm()->isolate()->counters(); 2177 Counters* counters = isolate()->counters();
2162 __ IncrementCounter(counters->call_const(), 1); 2178 __ IncrementCounter(counters->call_const(), 1);
2163 __ IncrementCounter(counters->call_const_fast_api(), 1); 2179 __ IncrementCounter(counters->call_const_fast_api(), 1);
2164 2180
2165 // Allocate space for v8::Arguments implicit values. Must be initialized 2181 // Allocate space for v8::Arguments implicit values. Must be initialized
2166 // before calling any runtime function. 2182 // before calling any runtime function.
2167 __ sub(Operand(esp), Immediate(kFastApiCallArguments * kPointerSize)); 2183 __ sub(Operand(esp), Immediate(kFastApiCallArguments * kPointerSize));
2168 2184
2169 // Check that the maps haven't changed and find a Holder as a side effect. 2185 // Check that the maps haven't changed and find a Holder as a side effect.
2170 CheckPrototypes(JSObject::cast(object), edx, holder, 2186 CheckPrototypes(JSObject::cast(object), edx, holder,
2171 ebx, eax, edi, name, depth, &miss); 2187 ebx, eax, edi, name, depth, &miss);
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
2227 __ j(zero, &miss, not_taken); 2243 __ j(zero, &miss, not_taken);
2228 } 2244 }
2229 2245
2230 // Make sure that it's okay not to patch the on stack receiver 2246 // Make sure that it's okay not to patch the on stack receiver
2231 // unless we're doing a receiver map check. 2247 // unless we're doing a receiver map check.
2232 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK); 2248 ASSERT(!object->IsGlobalObject() || check == RECEIVER_MAP_CHECK);
2233 2249
2234 SharedFunctionInfo* function_info = function->shared(); 2250 SharedFunctionInfo* function_info = function->shared();
2235 switch (check) { 2251 switch (check) {
2236 case RECEIVER_MAP_CHECK: 2252 case RECEIVER_MAP_CHECK:
2237 __ IncrementCounter(masm()->isolate()->counters()->call_const(), 1); 2253 __ IncrementCounter(isolate()->counters()->call_const(), 1);
2238 2254
2239 // Check that the maps haven't changed. 2255 // Check that the maps haven't changed.
2240 CheckPrototypes(JSObject::cast(object), edx, holder, 2256 CheckPrototypes(JSObject::cast(object), edx, holder,
2241 ebx, eax, edi, name, &miss); 2257 ebx, eax, edi, name, &miss);
2242 2258
2243 // Patch the receiver on the stack with the global proxy if 2259 // Patch the receiver on the stack with the global proxy if
2244 // necessary. 2260 // necessary.
2245 if (object->IsGlobalObject()) { 2261 if (object->IsGlobalObject()) {
2246 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); 2262 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
2247 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); 2263 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
(...skipping 179 matching lines...) Expand 10 before | Expand all | Expand 10 after
2427 // Patch the receiver on the stack with the global proxy. 2443 // Patch the receiver on the stack with the global proxy.
2428 if (object->IsGlobalObject()) { 2444 if (object->IsGlobalObject()) {
2429 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset)); 2445 __ mov(edx, FieldOperand(edx, GlobalObject::kGlobalReceiverOffset));
2430 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx); 2446 __ mov(Operand(esp, (argc + 1) * kPointerSize), edx);
2431 } 2447 }
2432 2448
2433 // Setup the context (function already in edi). 2449 // Setup the context (function already in edi).
2434 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset)); 2450 __ mov(esi, FieldOperand(edi, JSFunction::kContextOffset));
2435 2451
2436 // Jump to the cached code (tail call). 2452 // Jump to the cached code (tail call).
2437 Counters* counters = masm()->isolate()->counters(); 2453 Counters* counters = isolate()->counters();
2438 __ IncrementCounter(counters->call_global_inline(), 1); 2454 __ IncrementCounter(counters->call_global_inline(), 1);
2439 ASSERT(function->is_compiled()); 2455 ASSERT(function->is_compiled());
2440 ParameterCount expected(function->shared()->formal_parameter_count()); 2456 ParameterCount expected(function->shared()->formal_parameter_count());
2441 if (V8::UseCrankshaft()) { 2457 if (V8::UseCrankshaft()) {
2442 // TODO(kasperl): For now, we always call indirectly through the 2458 // TODO(kasperl): For now, we always call indirectly through the
2443 // code field in the function to allow recompilation to take effect 2459 // code field in the function to allow recompilation to take effect
2444 // without changing any of the call sites. 2460 // without changing any of the call sites.
2445 __ InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset), 2461 __ InvokeCode(FieldOperand(edi, JSFunction::kCodeEntryOffset),
2446 expected, arguments(), JUMP_FUNCTION); 2462 expected, arguments(), JUMP_FUNCTION);
2447 } else { 2463 } else {
(...skipping 29 matching lines...) Expand all
2477 GenerateStoreField(masm(), 2493 GenerateStoreField(masm(),
2478 object, 2494 object,
2479 index, 2495 index,
2480 transition, 2496 transition,
2481 edx, ecx, ebx, 2497 edx, ecx, ebx,
2482 &miss); 2498 &miss);
2483 2499
2484 // Handle store cache miss. 2500 // Handle store cache miss.
2485 __ bind(&miss); 2501 __ bind(&miss);
2486 __ mov(ecx, Immediate(Handle<String>(name))); // restore name 2502 __ mov(ecx, Immediate(Handle<String>(name))); // restore name
2487 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); 2503 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
2488 __ jmp(ic, RelocInfo::CODE_TARGET); 2504 __ jmp(ic, RelocInfo::CODE_TARGET);
2489 2505
2490 // Return the generated code. 2506 // Return the generated code.
2491 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); 2507 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name);
2492 } 2508 }
2493 2509
2494 2510
2495 MaybeObject* StoreStubCompiler::CompileStoreCallback(JSObject* object, 2511 MaybeObject* StoreStubCompiler::CompileStoreCallback(JSObject* object,
2496 AccessorInfo* callback, 2512 AccessorInfo* callback,
2497 String* name) { 2513 String* name) {
(...skipping 24 matching lines...) Expand all
2522 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded()); 2538 ASSERT(object->IsJSGlobalProxy() || !object->IsAccessCheckNeeded());
2523 2539
2524 __ pop(ebx); // remove the return address 2540 __ pop(ebx); // remove the return address
2525 __ push(edx); // receiver 2541 __ push(edx); // receiver
2526 __ push(Immediate(Handle<AccessorInfo>(callback))); // callback info 2542 __ push(Immediate(Handle<AccessorInfo>(callback))); // callback info
2527 __ push(ecx); // name 2543 __ push(ecx); // name
2528 __ push(eax); // value 2544 __ push(eax); // value
2529 __ push(ebx); // restore return address 2545 __ push(ebx); // restore return address
2530 2546
2531 // Do tail-call to the runtime system. 2547 // Do tail-call to the runtime system.
2532 Isolate* isolate = masm()->isolate();
2533 ExternalReference store_callback_property = 2548 ExternalReference store_callback_property =
2534 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate); 2549 ExternalReference(IC_Utility(IC::kStoreCallbackProperty), isolate());
2535 __ TailCallExternalReference(store_callback_property, 4, 1); 2550 __ TailCallExternalReference(store_callback_property, 4, 1);
2536 2551
2537 // Handle store cache miss. 2552 // Handle store cache miss.
2538 __ bind(&miss); 2553 __ bind(&miss);
2539 Handle<Code> ic = isolate->builtins()->StoreIC_Miss(); 2554 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
2540 __ jmp(ic, RelocInfo::CODE_TARGET); 2555 __ jmp(ic, RelocInfo::CODE_TARGET);
2541 2556
2542 // Return the generated code. 2557 // Return the generated code.
2543 return GetCode(CALLBACKS, name); 2558 return GetCode(CALLBACKS, name);
2544 } 2559 }
2545 2560
2546 2561
2547 MaybeObject* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver, 2562 MaybeObject* StoreStubCompiler::CompileStoreInterceptor(JSObject* receiver,
2548 String* name) { 2563 String* name) {
2549 // ----------- S t a t e ------------- 2564 // ----------- S t a t e -------------
(...skipping 23 matching lines...) Expand all
2573 ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded()); 2588 ASSERT(receiver->IsJSGlobalProxy() || !receiver->IsAccessCheckNeeded());
2574 2589
2575 __ pop(ebx); // remove the return address 2590 __ pop(ebx); // remove the return address
2576 __ push(edx); // receiver 2591 __ push(edx); // receiver
2577 __ push(ecx); // name 2592 __ push(ecx); // name
2578 __ push(eax); // value 2593 __ push(eax); // value
2579 __ push(Immediate(Smi::FromInt(strict_mode_))); 2594 __ push(Immediate(Smi::FromInt(strict_mode_)));
2580 __ push(ebx); // restore return address 2595 __ push(ebx); // restore return address
2581 2596
2582 // Do tail-call to the runtime system. 2597 // Do tail-call to the runtime system.
2583 Isolate* isolate = masm()->isolate();
2584 ExternalReference store_ic_property = 2598 ExternalReference store_ic_property =
2585 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate); 2599 ExternalReference(IC_Utility(IC::kStoreInterceptorProperty), isolate());
2586 __ TailCallExternalReference(store_ic_property, 4, 1); 2600 __ TailCallExternalReference(store_ic_property, 4, 1);
2587 2601
2588 // Handle store cache miss. 2602 // Handle store cache miss.
2589 __ bind(&miss); 2603 __ bind(&miss);
2590 Handle<Code> ic = isolate->builtins()->StoreIC_Miss(); 2604 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
2591 __ jmp(ic, RelocInfo::CODE_TARGET); 2605 __ jmp(ic, RelocInfo::CODE_TARGET);
2592 2606
2593 // Return the generated code. 2607 // Return the generated code.
2594 return GetCode(INTERCEPTOR, name); 2608 return GetCode(INTERCEPTOR, name);
2595 } 2609 }
2596 2610
2597 2611
2598 MaybeObject* StoreStubCompiler::CompileStoreGlobal(GlobalObject* object, 2612 MaybeObject* StoreStubCompiler::CompileStoreGlobal(GlobalObject* object,
2599 JSGlobalPropertyCell* cell, 2613 JSGlobalPropertyCell* cell,
2600 String* name) { 2614 String* name) {
(...skipping 22 matching lines...) Expand all
2623 // cell could have been deleted and reintroducing the global needs 2637 // cell could have been deleted and reintroducing the global needs
2624 // to update the property details in the property dictionary of the 2638 // to update the property details in the property dictionary of the
2625 // global object. We bail out to the runtime system to do that. 2639 // global object. We bail out to the runtime system to do that.
2626 __ cmp(cell_operand, FACTORY->the_hole_value()); 2640 __ cmp(cell_operand, FACTORY->the_hole_value());
2627 __ j(equal, &miss); 2641 __ j(equal, &miss);
2628 2642
2629 // Store the value in the cell. 2643 // Store the value in the cell.
2630 __ mov(cell_operand, eax); 2644 __ mov(cell_operand, eax);
2631 2645
2632 // Return the value (register eax). 2646 // Return the value (register eax).
2633 Counters* counters = masm()->isolate()->counters(); 2647 Counters* counters = isolate()->counters();
2634 __ IncrementCounter(counters->named_store_global_inline(), 1); 2648 __ IncrementCounter(counters->named_store_global_inline(), 1);
2635 __ ret(0); 2649 __ ret(0);
2636 2650
2637 // Handle store cache miss. 2651 // Handle store cache miss.
2638 __ bind(&miss); 2652 __ bind(&miss);
2639 __ IncrementCounter(counters->named_store_global_inline_miss(), 1); 2653 __ IncrementCounter(counters->named_store_global_inline_miss(), 1);
2640 Handle<Code> ic = masm()->isolate()->builtins()->StoreIC_Miss(); 2654 Handle<Code> ic = isolate()->builtins()->StoreIC_Miss();
2641 __ jmp(ic, RelocInfo::CODE_TARGET); 2655 __ jmp(ic, RelocInfo::CODE_TARGET);
2642 2656
2643 // Return the generated code. 2657 // Return the generated code.
2644 return GetCode(NORMAL, name); 2658 return GetCode(NORMAL, name);
2645 } 2659 }
2646 2660
2647 2661
2648 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object, 2662 MaybeObject* KeyedStoreStubCompiler::CompileStoreField(JSObject* object,
2649 int index, 2663 int index,
2650 Map* transition, 2664 Map* transition,
2651 String* name) { 2665 String* name) {
2652 // ----------- S t a t e ------------- 2666 // ----------- S t a t e -------------
2653 // -- eax : value 2667 // -- eax : value
2654 // -- ecx : key 2668 // -- ecx : key
2655 // -- edx : receiver 2669 // -- edx : receiver
2656 // -- esp[0] : return address 2670 // -- esp[0] : return address
2657 // ----------------------------------- 2671 // -----------------------------------
2658 Label miss; 2672 Label miss;
2659 2673
2660 Counters* counters = masm()->isolate()->counters(); 2674 Counters* counters = isolate()->counters();
2661 __ IncrementCounter(counters->keyed_store_field(), 1); 2675 __ IncrementCounter(counters->keyed_store_field(), 1);
2662 2676
2663 // Check that the name has not changed. 2677 // Check that the name has not changed.
2664 __ cmp(Operand(ecx), Immediate(Handle<String>(name))); 2678 __ cmp(Operand(ecx), Immediate(Handle<String>(name)));
2665 __ j(not_equal, &miss, not_taken); 2679 __ j(not_equal, &miss, not_taken);
2666 2680
2667 // Generate store field code. Trashes the name register. 2681 // Generate store field code. Trashes the name register.
2668 GenerateStoreField(masm(), 2682 GenerateStoreField(masm(),
2669 object, 2683 object,
2670 index, 2684 index,
2671 transition, 2685 transition,
2672 edx, ecx, ebx, 2686 edx, ecx, ebx,
2673 &miss); 2687 &miss);
2674 2688
2675 // Handle store cache miss. 2689 // Handle store cache miss.
2676 __ bind(&miss); 2690 __ bind(&miss);
2677 __ DecrementCounter(counters->keyed_store_field(), 1); 2691 __ DecrementCounter(counters->keyed_store_field(), 1);
2678 Handle<Code> ic = masm()->isolate()->builtins()->KeyedStoreIC_Miss(); 2692 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
2679 __ jmp(ic, RelocInfo::CODE_TARGET); 2693 __ jmp(ic, RelocInfo::CODE_TARGET);
2680 2694
2681 // Return the generated code. 2695 // Return the generated code.
2682 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name); 2696 return GetCode(transition == NULL ? FIELD : MAP_TRANSITION, name);
2683 } 2697 }
2684 2698
2685 2699
2686 MaybeObject* KeyedStoreStubCompiler::CompileStoreSpecialized( 2700 MaybeObject* KeyedStoreStubCompiler::CompileStoreSpecialized(
2687 JSObject* receiver) { 2701 JSObject* receiver) {
2688 // ----------- S t a t e ------------- 2702 // ----------- S t a t e -------------
(...skipping 36 matching lines...) Expand 10 before | Expand all | Expand 10 after
2725 // the value in register eax. 2739 // the value in register eax.
2726 __ mov(edx, Operand(eax)); 2740 __ mov(edx, Operand(eax));
2727 __ mov(FieldOperand(edi, ecx, times_2, FixedArray::kHeaderSize), eax); 2741 __ mov(FieldOperand(edi, ecx, times_2, FixedArray::kHeaderSize), eax);
2728 __ RecordWrite(edi, 0, edx, ecx); 2742 __ RecordWrite(edi, 0, edx, ecx);
2729 2743
2730 // Done. 2744 // Done.
2731 __ ret(0); 2745 __ ret(0);
2732 2746
2733 // Handle store cache miss. 2747 // Handle store cache miss.
2734 __ bind(&miss); 2748 __ bind(&miss);
2735 Handle<Code> ic = masm()->isolate()->builtins()->KeyedStoreIC_Miss(); 2749 Handle<Code> ic = isolate()->builtins()->KeyedStoreIC_Miss();
2736 __ jmp(ic, RelocInfo::CODE_TARGET); 2750 __ jmp(ic, RelocInfo::CODE_TARGET);
2737 2751
2738 // Return the generated code. 2752 // Return the generated code.
2739 return GetCode(NORMAL, NULL); 2753 return GetCode(NORMAL, NULL);
2740 } 2754 }
2741 2755
2742 2756
2743 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name, 2757 MaybeObject* LoadStubCompiler::CompileLoadNonexistent(String* name,
2744 JSObject* object, 2758 JSObject* object,
2745 JSObject* last) { 2759 JSObject* last) {
(...skipping 24 matching lines...) Expand all
2770 edx, 2784 edx,
2771 &miss); 2785 &miss);
2772 if (cell->IsFailure()) { 2786 if (cell->IsFailure()) {
2773 miss.Unuse(); 2787 miss.Unuse();
2774 return cell; 2788 return cell;
2775 } 2789 }
2776 } 2790 }
2777 2791
2778 // Return undefined if maps of the full prototype chain are still the 2792 // Return undefined if maps of the full prototype chain are still the
2779 // same and no global property with this name contains a value. 2793 // same and no global property with this name contains a value.
2780 __ mov(eax, FACTORY->undefined_value()); 2794 __ mov(eax, isolate()->factory()->undefined_value());
2781 __ ret(0); 2795 __ ret(0);
2782 2796
2783 __ bind(&miss); 2797 __ bind(&miss);
2784 GenerateLoadMiss(masm(), Code::LOAD_IC); 2798 GenerateLoadMiss(masm(), Code::LOAD_IC);
2785 2799
2786 // Return the generated code. 2800 // Return the generated code.
2787 return GetCode(NONEXISTENT, HEAP->empty_string()); 2801 return GetCode(NONEXISTENT, isolate()->heap()->empty_string());
2788 } 2802 }
2789 2803
2790 2804
2791 MaybeObject* LoadStubCompiler::CompileLoadField(JSObject* object, 2805 MaybeObject* LoadStubCompiler::CompileLoadField(JSObject* object,
2792 JSObject* holder, 2806 JSObject* holder,
2793 int index, 2807 int index,
2794 String* name) { 2808 String* name) {
2795 // ----------- S t a t e ------------- 2809 // ----------- S t a t e -------------
2796 // -- eax : receiver 2810 // -- eax : receiver
2797 // -- ecx : name 2811 // -- ecx : name
(...skipping 123 matching lines...) Expand 10 before | Expand all | Expand 10 after
2921 2935
2922 // Check for deleted property if property can actually be deleted. 2936 // Check for deleted property if property can actually be deleted.
2923 if (!is_dont_delete) { 2937 if (!is_dont_delete) {
2924 __ cmp(ebx, FACTORY->the_hole_value()); 2938 __ cmp(ebx, FACTORY->the_hole_value());
2925 __ j(equal, &miss, not_taken); 2939 __ j(equal, &miss, not_taken);
2926 } else if (FLAG_debug_code) { 2940 } else if (FLAG_debug_code) {
2927 __ cmp(ebx, FACTORY->the_hole_value()); 2941 __ cmp(ebx, FACTORY->the_hole_value());
2928 __ Check(not_equal, "DontDelete cells can't contain the hole"); 2942 __ Check(not_equal, "DontDelete cells can't contain the hole");
2929 } 2943 }
2930 2944
2931 Counters* counters = masm()->isolate()->counters(); 2945 Counters* counters = isolate()->counters();
2932 __ IncrementCounter(counters->named_load_global_stub(), 1); 2946 __ IncrementCounter(counters->named_load_global_stub(), 1);
2933 __ mov(eax, ebx); 2947 __ mov(eax, ebx);
2934 __ ret(0); 2948 __ ret(0);
2935 2949
2936 __ bind(&miss); 2950 __ bind(&miss);
2937 __ IncrementCounter(counters->named_load_global_stub_miss(), 1); 2951 __ IncrementCounter(counters->named_load_global_stub_miss(), 1);
2938 GenerateLoadMiss(masm(), Code::LOAD_IC); 2952 GenerateLoadMiss(masm(), Code::LOAD_IC);
2939 2953
2940 // Return the generated code. 2954 // Return the generated code.
2941 return GetCode(NORMAL, name); 2955 return GetCode(NORMAL, name);
2942 } 2956 }
2943 2957
2944 2958
2945 MaybeObject* KeyedLoadStubCompiler::CompileLoadField(String* name, 2959 MaybeObject* KeyedLoadStubCompiler::CompileLoadField(String* name,
2946 JSObject* receiver, 2960 JSObject* receiver,
2947 JSObject* holder, 2961 JSObject* holder,
2948 int index) { 2962 int index) {
2949 // ----------- S t a t e ------------- 2963 // ----------- S t a t e -------------
2950 // -- eax : key 2964 // -- eax : key
2951 // -- edx : receiver 2965 // -- edx : receiver
2952 // -- esp[0] : return address 2966 // -- esp[0] : return address
2953 // ----------------------------------- 2967 // -----------------------------------
2954 Label miss; 2968 Label miss;
2955 2969
2956 Counters* counters = masm()->isolate()->counters(); 2970 Counters* counters = isolate()->counters();
2957 __ IncrementCounter(counters->keyed_load_field(), 1); 2971 __ IncrementCounter(counters->keyed_load_field(), 1);
2958 2972
2959 // Check that the name has not changed. 2973 // Check that the name has not changed.
2960 __ cmp(Operand(eax), Immediate(Handle<String>(name))); 2974 __ cmp(Operand(eax), Immediate(Handle<String>(name)));
2961 __ j(not_equal, &miss, not_taken); 2975 __ j(not_equal, &miss, not_taken);
2962 2976
2963 GenerateLoadField(receiver, holder, edx, ebx, ecx, edi, index, name, &miss); 2977 GenerateLoadField(receiver, holder, edx, ebx, ecx, edi, index, name, &miss);
2964 2978
2965 __ bind(&miss); 2979 __ bind(&miss);
2966 __ DecrementCounter(counters->keyed_load_field(), 1); 2980 __ DecrementCounter(counters->keyed_load_field(), 1);
2967 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 2981 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
2968 2982
2969 // Return the generated code. 2983 // Return the generated code.
2970 return GetCode(FIELD, name); 2984 return GetCode(FIELD, name);
2971 } 2985 }
2972 2986
2973 2987
2974 MaybeObject* KeyedLoadStubCompiler::CompileLoadCallback( 2988 MaybeObject* KeyedLoadStubCompiler::CompileLoadCallback(
2975 String* name, 2989 String* name,
2976 JSObject* receiver, 2990 JSObject* receiver,
2977 JSObject* holder, 2991 JSObject* holder,
2978 AccessorInfo* callback) { 2992 AccessorInfo* callback) {
2979 // ----------- S t a t e ------------- 2993 // ----------- S t a t e -------------
2980 // -- eax : key 2994 // -- eax : key
2981 // -- edx : receiver 2995 // -- edx : receiver
2982 // -- esp[0] : return address 2996 // -- esp[0] : return address
2983 // ----------------------------------- 2997 // -----------------------------------
2984 Label miss; 2998 Label miss;
2985 2999
2986 Counters* counters = masm()->isolate()->counters(); 3000 Counters* counters = isolate()->counters();
2987 __ IncrementCounter(counters->keyed_load_callback(), 1); 3001 __ IncrementCounter(counters->keyed_load_callback(), 1);
2988 3002
2989 // Check that the name has not changed. 3003 // Check that the name has not changed.
2990 __ cmp(Operand(eax), Immediate(Handle<String>(name))); 3004 __ cmp(Operand(eax), Immediate(Handle<String>(name)));
2991 __ j(not_equal, &miss, not_taken); 3005 __ j(not_equal, &miss, not_taken);
2992 3006
2993 MaybeObject* result = GenerateLoadCallback(receiver, holder, edx, eax, ebx, 3007 MaybeObject* result = GenerateLoadCallback(receiver, holder, edx, eax, ebx,
2994 ecx, edi, callback, name, &miss); 3008 ecx, edi, callback, name, &miss);
2995 if (result->IsFailure()) { 3009 if (result->IsFailure()) {
2996 miss.Unuse(); 3010 miss.Unuse();
(...skipping 14 matching lines...) Expand all
3011 JSObject* receiver, 3025 JSObject* receiver,
3012 JSObject* holder, 3026 JSObject* holder,
3013 Object* value) { 3027 Object* value) {
3014 // ----------- S t a t e ------------- 3028 // ----------- S t a t e -------------
3015 // -- eax : key 3029 // -- eax : key
3016 // -- edx : receiver 3030 // -- edx : receiver
3017 // -- esp[0] : return address 3031 // -- esp[0] : return address
3018 // ----------------------------------- 3032 // -----------------------------------
3019 Label miss; 3033 Label miss;
3020 3034
3021 Counters* counters = masm()->isolate()->counters(); 3035 Counters* counters = isolate()->counters();
3022 __ IncrementCounter(counters->keyed_load_constant_function(), 1); 3036 __ IncrementCounter(counters->keyed_load_constant_function(), 1);
3023 3037
3024 // Check that the name has not changed. 3038 // Check that the name has not changed.
3025 __ cmp(Operand(eax), Immediate(Handle<String>(name))); 3039 __ cmp(Operand(eax), Immediate(Handle<String>(name)));
3026 __ j(not_equal, &miss, not_taken); 3040 __ j(not_equal, &miss, not_taken);
3027 3041
3028 GenerateLoadConstant(receiver, holder, edx, ebx, ecx, edi, 3042 GenerateLoadConstant(receiver, holder, edx, ebx, ecx, edi,
3029 value, name, &miss); 3043 value, name, &miss);
3030 __ bind(&miss); 3044 __ bind(&miss);
3031 __ DecrementCounter(counters->keyed_load_constant_function(), 1); 3045 __ DecrementCounter(counters->keyed_load_constant_function(), 1);
3032 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3046 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3033 3047
3034 // Return the generated code. 3048 // Return the generated code.
3035 return GetCode(CONSTANT_FUNCTION, name); 3049 return GetCode(CONSTANT_FUNCTION, name);
3036 } 3050 }
3037 3051
3038 3052
3039 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver, 3053 MaybeObject* KeyedLoadStubCompiler::CompileLoadInterceptor(JSObject* receiver,
3040 JSObject* holder, 3054 JSObject* holder,
3041 String* name) { 3055 String* name) {
3042 // ----------- S t a t e ------------- 3056 // ----------- S t a t e -------------
3043 // -- eax : key 3057 // -- eax : key
3044 // -- edx : receiver 3058 // -- edx : receiver
3045 // -- esp[0] : return address 3059 // -- esp[0] : return address
3046 // ----------------------------------- 3060 // -----------------------------------
3047 Label miss; 3061 Label miss;
3048 3062
3049 Counters* counters = masm()->isolate()->counters(); 3063 Counters* counters = isolate()->counters();
3050 __ IncrementCounter(counters->keyed_load_interceptor(), 1); 3064 __ IncrementCounter(counters->keyed_load_interceptor(), 1);
3051 3065
3052 // Check that the name has not changed. 3066 // Check that the name has not changed.
3053 __ cmp(Operand(eax), Immediate(Handle<String>(name))); 3067 __ cmp(Operand(eax), Immediate(Handle<String>(name)));
3054 __ j(not_equal, &miss, not_taken); 3068 __ j(not_equal, &miss, not_taken);
3055 3069
3056 LookupResult lookup; 3070 LookupResult lookup;
3057 LookupPostInterceptor(holder, name, &lookup); 3071 LookupPostInterceptor(holder, name, &lookup);
3058 GenerateLoadInterceptor(receiver, 3072 GenerateLoadInterceptor(receiver,
3059 holder, 3073 holder,
(...skipping 15 matching lines...) Expand all
3075 3089
3076 3090
3077 MaybeObject* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) { 3091 MaybeObject* KeyedLoadStubCompiler::CompileLoadArrayLength(String* name) {
3078 // ----------- S t a t e ------------- 3092 // ----------- S t a t e -------------
3079 // -- eax : key 3093 // -- eax : key
3080 // -- edx : receiver 3094 // -- edx : receiver
3081 // -- esp[0] : return address 3095 // -- esp[0] : return address
3082 // ----------------------------------- 3096 // -----------------------------------
3083 Label miss; 3097 Label miss;
3084 3098
3085 Counters* counters = masm()->isolate()->counters(); 3099 Counters* counters = isolate()->counters();
3086 __ IncrementCounter(counters->keyed_load_array_length(), 1); 3100 __ IncrementCounter(counters->keyed_load_array_length(), 1);
3087 3101
3088 // Check that the name has not changed. 3102 // Check that the name has not changed.
3089 __ cmp(Operand(eax), Immediate(Handle<String>(name))); 3103 __ cmp(Operand(eax), Immediate(Handle<String>(name)));
3090 __ j(not_equal, &miss, not_taken); 3104 __ j(not_equal, &miss, not_taken);
3091 3105
3092 GenerateLoadArrayLength(masm(), edx, ecx, &miss); 3106 GenerateLoadArrayLength(masm(), edx, ecx, &miss);
3093 __ bind(&miss); 3107 __ bind(&miss);
3094 __ DecrementCounter(counters->keyed_load_array_length(), 1); 3108 __ DecrementCounter(counters->keyed_load_array_length(), 1);
3095 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3109 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3096 3110
3097 // Return the generated code. 3111 // Return the generated code.
3098 return GetCode(CALLBACKS, name); 3112 return GetCode(CALLBACKS, name);
3099 } 3113 }
3100 3114
3101 3115
3102 MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) { 3116 MaybeObject* KeyedLoadStubCompiler::CompileLoadStringLength(String* name) {
3103 // ----------- S t a t e ------------- 3117 // ----------- S t a t e -------------
3104 // -- eax : key 3118 // -- eax : key
3105 // -- edx : receiver 3119 // -- edx : receiver
3106 // -- esp[0] : return address 3120 // -- esp[0] : return address
3107 // ----------------------------------- 3121 // -----------------------------------
3108 Label miss; 3122 Label miss;
3109 3123
3110 Counters* counters = masm()->isolate()->counters(); 3124 Counters* counters = isolate()->counters();
3111 __ IncrementCounter(counters->keyed_load_string_length(), 1); 3125 __ IncrementCounter(counters->keyed_load_string_length(), 1);
3112 3126
3113 // Check that the name has not changed. 3127 // Check that the name has not changed.
3114 __ cmp(Operand(eax), Immediate(Handle<String>(name))); 3128 __ cmp(Operand(eax), Immediate(Handle<String>(name)));
3115 __ j(not_equal, &miss, not_taken); 3129 __ j(not_equal, &miss, not_taken);
3116 3130
3117 GenerateLoadStringLength(masm(), edx, ecx, ebx, &miss, true); 3131 GenerateLoadStringLength(masm(), edx, ecx, ebx, &miss, true);
3118 __ bind(&miss); 3132 __ bind(&miss);
3119 __ DecrementCounter(counters->keyed_load_string_length(), 1); 3133 __ DecrementCounter(counters->keyed_load_string_length(), 1);
3120 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3134 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
3121 3135
3122 // Return the generated code. 3136 // Return the generated code.
3123 return GetCode(CALLBACKS, name); 3137 return GetCode(CALLBACKS, name);
3124 } 3138 }
3125 3139
3126 3140
3127 MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) { 3141 MaybeObject* KeyedLoadStubCompiler::CompileLoadFunctionPrototype(String* name) {
3128 // ----------- S t a t e ------------- 3142 // ----------- S t a t e -------------
3129 // -- eax : key 3143 // -- eax : key
3130 // -- edx : receiver 3144 // -- edx : receiver
3131 // -- esp[0] : return address 3145 // -- esp[0] : return address
3132 // ----------------------------------- 3146 // -----------------------------------
3133 Label miss; 3147 Label miss;
3134 3148
3135 Counters* counters = masm()->isolate()->counters(); 3149 Counters* counters = isolate()->counters();
3136 __ IncrementCounter(counters->keyed_load_function_prototype(), 1); 3150 __ IncrementCounter(counters->keyed_load_function_prototype(), 1);
3137 3151
3138 // Check that the name has not changed. 3152 // Check that the name has not changed.
3139 __ cmp(Operand(eax), Immediate(Handle<String>(name))); 3153 __ cmp(Operand(eax), Immediate(Handle<String>(name)));
3140 __ j(not_equal, &miss, not_taken); 3154 __ j(not_equal, &miss, not_taken);
3141 3155
3142 GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss); 3156 GenerateLoadFunctionPrototype(masm(), edx, ecx, ebx, &miss);
3143 __ bind(&miss); 3157 __ bind(&miss);
3144 __ DecrementCounter(counters->keyed_load_function_prototype(), 1); 3158 __ DecrementCounter(counters->keyed_load_function_prototype(), 1);
3145 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC); 3159 GenerateLoadMiss(masm(), Code::KEYED_LOAD_IC);
(...skipping 128 matching lines...) Expand 10 before | Expand all | Expand 10 after
3274 // depending on the this.x = ...; assignment in the function. 3288 // depending on the this.x = ...; assignment in the function.
3275 SharedFunctionInfo* shared = function->shared(); 3289 SharedFunctionInfo* shared = function->shared();
3276 for (int i = 0; i < shared->this_property_assignments_count(); i++) { 3290 for (int i = 0; i < shared->this_property_assignments_count(); i++) {
3277 if (shared->IsThisPropertyAssignmentArgument(i)) { 3291 if (shared->IsThisPropertyAssignmentArgument(i)) {
3278 // Check if the argument assigned to the property is actually passed. 3292 // Check if the argument assigned to the property is actually passed.
3279 // If argument is not passed the property is set to undefined, 3293 // If argument is not passed the property is set to undefined,
3280 // otherwise find it on the stack. 3294 // otherwise find it on the stack.
3281 int arg_number = shared->GetThisPropertyAssignmentArgument(i); 3295 int arg_number = shared->GetThisPropertyAssignmentArgument(i);
3282 __ mov(ebx, edi); 3296 __ mov(ebx, edi);
3283 __ cmp(eax, arg_number); 3297 __ cmp(eax, arg_number);
3284 if (masm()->isolate()->cpu_features()->IsSupported(CMOV)) { 3298 if (isolate()->cpu_features()->IsSupported(CMOV)) {
3285 CpuFeatures::Scope use_cmov(CMOV); 3299 CpuFeatures::Scope use_cmov(CMOV);
3286 __ cmov(above, ebx, Operand(ecx, arg_number * -kPointerSize)); 3300 __ cmov(above, ebx, Operand(ecx, arg_number * -kPointerSize));
3287 } else { 3301 } else {
3288 Label not_passed; 3302 Label not_passed;
3289 __ j(below_equal, &not_passed); 3303 __ j(below_equal, &not_passed);
3290 __ mov(ebx, Operand(ecx, arg_number * -kPointerSize)); 3304 __ mov(ebx, Operand(ecx, arg_number * -kPointerSize));
3291 __ bind(&not_passed); 3305 __ bind(&not_passed);
3292 } 3306 }
3293 // Store value in the property. 3307 // Store value in the property.
3294 __ mov(Operand(edx, i * kPointerSize), ebx); 3308 __ mov(Operand(edx, i * kPointerSize), ebx);
(...skipping 14 matching lines...) Expand all
3309 3323
3310 // Move argc to ebx and retrieve and tag the JSObject to return. 3324 // Move argc to ebx and retrieve and tag the JSObject to return.
3311 __ mov(ebx, eax); 3325 __ mov(ebx, eax);
3312 __ pop(eax); 3326 __ pop(eax);
3313 __ or_(Operand(eax), Immediate(kHeapObjectTag)); 3327 __ or_(Operand(eax), Immediate(kHeapObjectTag));
3314 3328
3315 // Remove caller arguments and receiver from the stack and return. 3329 // Remove caller arguments and receiver from the stack and return.
3316 __ pop(ecx); 3330 __ pop(ecx);
3317 __ lea(esp, Operand(esp, ebx, times_pointer_size, 1 * kPointerSize)); 3331 __ lea(esp, Operand(esp, ebx, times_pointer_size, 1 * kPointerSize));
3318 __ push(ecx); 3332 __ push(ecx);
3319 Counters* counters = masm()->isolate()->counters(); 3333 Counters* counters = isolate()->counters();
3320 __ IncrementCounter(counters->constructed_objects(), 1); 3334 __ IncrementCounter(counters->constructed_objects(), 1);
3321 __ IncrementCounter(counters->constructed_objects_stub(), 1); 3335 __ IncrementCounter(counters->constructed_objects_stub(), 1);
3322 __ ret(0); 3336 __ ret(0);
3323 3337
3324 // Jump to the generic stub in case the specialized code cannot handle the 3338 // Jump to the generic stub in case the specialized code cannot handle the
3325 // construction. 3339 // construction.
3326 __ bind(&generic_stub_call); 3340 __ bind(&generic_stub_call);
3327 Handle<Code> generic_construct_stub = 3341 Handle<Code> generic_construct_stub =
3328 masm()->isolate()->builtins()->JSConstructStubGeneric(); 3342 isolate()->builtins()->JSConstructStubGeneric();
3329 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET); 3343 __ jmp(generic_construct_stub, RelocInfo::CODE_TARGET);
3330 3344
3331 // Return the generated code. 3345 // Return the generated code.
3332 return GetCode(); 3346 return GetCode();
3333 } 3347 }
3334 3348
3335 3349
3336 MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub( 3350 MaybeObject* ExternalArrayStubCompiler::CompileKeyedLoadStub(
3337 JSObject*receiver, ExternalArrayType array_type, Code::Flags flags) { 3351 JSObject*receiver, ExternalArrayType array_type, Code::Flags flags) {
3338 // ----------- S t a t e ------------- 3352 // ----------- S t a t e -------------
(...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after
3458 3472
3459 // If we fail allocation of the HeapNumber, we still have a value on 3473 // If we fail allocation of the HeapNumber, we still have a value on
3460 // top of the FPU stack. Remove it. 3474 // top of the FPU stack. Remove it.
3461 __ bind(&failed_allocation); 3475 __ bind(&failed_allocation);
3462 __ ffree(); 3476 __ ffree();
3463 __ fincstp(); 3477 __ fincstp();
3464 // Fall through to slow case. 3478 // Fall through to slow case.
3465 3479
3466 // Slow case: Jump to runtime. 3480 // Slow case: Jump to runtime.
3467 __ bind(&slow); 3481 __ bind(&slow);
3468 Counters* counters = masm()->isolate()->counters(); 3482 Counters* counters = isolate()->counters();
3469 __ IncrementCounter(counters->keyed_load_external_array_slow(), 1); 3483 __ IncrementCounter(counters->keyed_load_external_array_slow(), 1);
3470 // ----------- S t a t e ------------- 3484 // ----------- S t a t e -------------
3471 // -- eax : key 3485 // -- eax : key
3472 // -- edx : receiver 3486 // -- edx : receiver
3473 // -- esp[0] : return address 3487 // -- esp[0] : return address
3474 // ----------------------------------- 3488 // -----------------------------------
3475 3489
3476 __ pop(ebx); 3490 __ pop(ebx);
3477 __ push(edx); // receiver 3491 __ push(edx); // receiver
3478 __ push(eax); // name 3492 __ push(eax); // name
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after
3593 __ fstp_s(Operand(edi, ebx, times_4, 0)); 3607 __ fstp_s(Operand(edi, ebx, times_4, 0));
3594 __ ret(0); 3608 __ ret(0);
3595 } else { 3609 } else {
3596 // Perform float-to-int conversion with truncation (round-to-zero) 3610 // Perform float-to-int conversion with truncation (round-to-zero)
3597 // behavior. 3611 // behavior.
3598 3612
3599 // For the moment we make the slow call to the runtime on 3613 // For the moment we make the slow call to the runtime on
3600 // processors that don't support SSE2. The code in IntegerConvert 3614 // processors that don't support SSE2. The code in IntegerConvert
3601 // (code-stubs-ia32.cc) is roughly what is needed here though the 3615 // (code-stubs-ia32.cc) is roughly what is needed here though the
3602 // conversion failure case does not need to be handled. 3616 // conversion failure case does not need to be handled.
3603 if (masm()->isolate()->cpu_features()->IsSupported(SSE2)) { 3617 if (isolate()->cpu_features()->IsSupported(SSE2)) {
3604 if (array_type != kExternalIntArray && 3618 if (array_type != kExternalIntArray &&
3605 array_type != kExternalUnsignedIntArray) { 3619 array_type != kExternalUnsignedIntArray) {
3606 ASSERT(masm()->isolate()->cpu_features()->IsSupported(SSE2)); 3620 ASSERT(isolate()->cpu_features()->IsSupported(SSE2));
3607 CpuFeatures::Scope scope(SSE2); 3621 CpuFeatures::Scope scope(SSE2);
3608 __ cvttsd2si(ecx, FieldOperand(eax, HeapNumber::kValueOffset)); 3622 __ cvttsd2si(ecx, FieldOperand(eax, HeapNumber::kValueOffset));
3609 // ecx: untagged integer value 3623 // ecx: untagged integer value
3610 switch (array_type) { 3624 switch (array_type) {
3611 case kExternalPixelArray: 3625 case kExternalPixelArray:
3612 { // Clamp the value to [0..255]. 3626 { // Clamp the value to [0..255].
3613 NearLabel done; 3627 NearLabel done;
3614 __ test(ecx, Immediate(0xFFFFFF00)); 3628 __ test(ecx, Immediate(0xFFFFFF00));
3615 __ j(zero, &done); 3629 __ j(zero, &done);
3616 __ setcc(negative, ecx); // 1 if negative, 0 if positive. 3630 __ setcc(negative, ecx); // 1 if negative, 0 if positive.
3617 __ dec_b(ecx); // 0 if negative, 255 if positive. 3631 __ dec_b(ecx); // 0 if negative, 255 if positive.
3618 __ bind(&done); 3632 __ bind(&done);
3619 } 3633 }
3620 __ mov_b(Operand(edi, ebx, times_1, 0), ecx); 3634 __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
3621 case kExternalByteArray: 3635 case kExternalByteArray:
3622 case kExternalUnsignedByteArray: 3636 case kExternalUnsignedByteArray:
3623 __ mov_b(Operand(edi, ebx, times_1, 0), ecx); 3637 __ mov_b(Operand(edi, ebx, times_1, 0), ecx);
3624 break; 3638 break;
3625 case kExternalShortArray: 3639 case kExternalShortArray:
3626 case kExternalUnsignedShortArray: 3640 case kExternalUnsignedShortArray:
3627 __ mov_w(Operand(edi, ebx, times_2, 0), ecx); 3641 __ mov_w(Operand(edi, ebx, times_2, 0), ecx);
3628 break; 3642 break;
3629 default: 3643 default:
3630 UNREACHABLE(); 3644 UNREACHABLE();
3631 break; 3645 break;
3632 } 3646 }
3633 } else { 3647 } else {
3634 if (masm()->isolate()->cpu_features()->IsSupported(SSE3)) { 3648 if (isolate()->cpu_features()->IsSupported(SSE3)) {
3635 CpuFeatures::Scope scope(SSE3); 3649 CpuFeatures::Scope scope(SSE3);
3636 // fisttp stores values as signed integers. To represent the 3650 // fisttp stores values as signed integers. To represent the
3637 // entire range of int and unsigned int arrays, store as a 3651 // entire range of int and unsigned int arrays, store as a
3638 // 64-bit int and discard the high 32 bits. 3652 // 64-bit int and discard the high 32 bits.
3639 // If the value is NaN or +/-infinity, the result is 0x80000000, 3653 // If the value is NaN or +/-infinity, the result is 0x80000000,
3640 // which is automatically zero when taken mod 2^n, n < 32. 3654 // which is automatically zero when taken mod 2^n, n < 32.
3641 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); 3655 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset));
3642 __ sub(Operand(esp), Immediate(2 * kPointerSize)); 3656 __ sub(Operand(esp), Immediate(2 * kPointerSize));
3643 __ fisttp_d(Operand(esp, 0)); 3657 __ fisttp_d(Operand(esp, 0));
3644 __ pop(ecx); 3658 __ pop(ecx);
3645 __ add(Operand(esp), Immediate(kPointerSize)); 3659 __ add(Operand(esp), Immediate(kPointerSize));
3646 } else { 3660 } else {
3647 ASSERT(masm()->isolate()->cpu_features()->IsSupported(SSE2)); 3661 ASSERT(isolate()->cpu_features()->IsSupported(SSE2));
3648 CpuFeatures::Scope scope(SSE2); 3662 CpuFeatures::Scope scope(SSE2);
3649 // We can easily implement the correct rounding behavior for the 3663 // We can easily implement the correct rounding behavior for the
3650 // range [0, 2^31-1]. For the time being, to keep this code simple, 3664 // range [0, 2^31-1]. For the time being, to keep this code simple,
3651 // make the slow runtime call for values outside this range. 3665 // make the slow runtime call for values outside this range.
3652 // Note: we could do better for signed int arrays. 3666 // Note: we could do better for signed int arrays.
3653 __ movd(xmm0, FieldOperand(eax, HeapNumber::kValueOffset)); 3667 __ movd(xmm0, FieldOperand(eax, HeapNumber::kValueOffset));
3654 // We will need the key if we have to make the slow runtime call. 3668 // We will need the key if we have to make the slow runtime call.
3655 __ push(ecx); 3669 __ push(ecx);
3656 __ LoadPowerOf2(xmm1, ecx, 31); 3670 __ LoadPowerOf2(xmm1, ecx, 31);
3657 __ pop(ecx); 3671 __ pop(ecx);
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
3690 3704
3691 return GetCode(flags); 3705 return GetCode(flags);
3692 } 3706 }
3693 3707
3694 3708
3695 #undef __ 3709 #undef __
3696 3710
3697 } } // namespace v8::internal 3711 } } // namespace v8::internal
3698 3712
3699 #endif // V8_TARGET_ARCH_IA32 3713 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/macro-assembler-ia32.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698