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

Side by Side Diff: src/ia32/code-stubs-ia32.cc

Issue 7535004: Merge bleeding edge up to 8774 into the GC branch. (Closed) Base URL: http://v8.googlecode.com/svn/branches/experimental/gc/
Patch Set: Created 9 years, 4 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/code-stubs-ia32.h ('k') | src/ia32/codegen-ia32.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2011 the V8 project authors. All rights reserved. 1 // Copyright 2011 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 218 matching lines...) Expand 10 before | Expand all | Expand 10 after
229 } 229 }
230 230
231 // Return and remove the on-stack parameters. 231 // Return and remove the on-stack parameters.
232 __ ret(3 * kPointerSize); 232 __ ret(3 * kPointerSize);
233 233
234 __ bind(&slow_case); 234 __ bind(&slow_case);
235 __ TailCallRuntime(Runtime::kCreateArrayLiteralShallow, 3, 1); 235 __ TailCallRuntime(Runtime::kCreateArrayLiteralShallow, 3, 1);
236 } 236 }
237 237
238 238
239 // The stub returns zero for false, and a non-zero value for true. 239 // The stub expects its argument on the stack and returns its result in tos_:
240 // zero for false, and a non-zero value for true.
240 void ToBooleanStub::Generate(MacroAssembler* masm) { 241 void ToBooleanStub::Generate(MacroAssembler* masm) {
241 Label false_result, true_result, not_string; 242 Label patch;
242 Factory* factory = masm->isolate()->factory(); 243 Factory* factory = masm->isolate()->factory();
244 const Register argument = eax;
243 const Register map = edx; 245 const Register map = edx;
244 246
245 __ mov(eax, Operand(esp, 1 * kPointerSize)); 247 if (!types_.IsEmpty()) {
248 __ mov(argument, Operand(esp, 1 * kPointerSize));
249 }
246 250
247 // undefined -> false 251 // undefined -> false
248 __ cmp(eax, factory->undefined_value()); 252 CheckOddball(masm, UNDEFINED, Heap::kUndefinedValueRootIndex, false, &patch);
249 __ j(equal, &false_result);
250 253
251 // Boolean -> its value 254 // Boolean -> its value
252 __ cmp(eax, factory->false_value()); 255 CheckOddball(masm, BOOLEAN, Heap::kFalseValueRootIndex, false, &patch);
253 __ j(equal, &false_result); 256 CheckOddball(masm, BOOLEAN, Heap::kTrueValueRootIndex, true, &patch);
254 __ cmp(eax, factory->true_value());
255 __ j(equal, &true_result);
256
257 // Smis: 0 -> false, all other -> true
258 __ test(eax, Operand(eax));
259 __ j(zero, &false_result);
260 __ JumpIfSmi(eax, &true_result);
261 257
262 // 'null' -> false. 258 // 'null' -> false.
263 __ cmp(eax, factory->null_value()); 259 CheckOddball(masm, NULL_TYPE, Heap::kNullValueRootIndex, false, &patch);
264 __ j(equal, &false_result, Label::kNear);
265 260
266 // Get the map of the heap object. 261 if (types_.Contains(SMI)) {
267 __ mov(map, FieldOperand(eax, HeapObject::kMapOffset)); 262 // Smis: 0 -> false, all other -> true
263 Label not_smi;
264 __ JumpIfNotSmi(argument, &not_smi, Label::kNear);
265 // argument contains the correct return value already
266 if (!tos_.is(argument)) {
267 __ mov(tos_, argument);
268 }
269 __ ret(1 * kPointerSize);
270 __ bind(&not_smi);
271 } else if (types_.NeedsMap()) {
272 // If we need a map later and have a Smi -> patch.
273 __ JumpIfSmi(argument, &patch, Label::kNear);
274 }
268 275
269 // Undetectable -> false. 276 if (types_.NeedsMap()) {
270 __ test_b(FieldOperand(map, Map::kBitFieldOffset), 277 __ mov(map, FieldOperand(argument, HeapObject::kMapOffset));
271 1 << Map::kIsUndetectable);
272 __ j(not_zero, &false_result, Label::kNear);
273 278
274 // JavaScript object -> true. 279 // Everything with a map could be undetectable, so check this now.
275 __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE); 280 __ test_b(FieldOperand(map, Map::kBitFieldOffset),
276 __ j(above_equal, &true_result, Label::kNear); 281 1 << Map::kIsUndetectable);
282 // Undetectable -> false.
283 Label not_undetectable;
284 __ j(zero, &not_undetectable, Label::kNear);
285 __ Set(tos_, Immediate(0));
286 __ ret(1 * kPointerSize);
287 __ bind(&not_undetectable);
288 }
277 289
278 // String value -> false iff empty. 290 if (types_.Contains(SPEC_OBJECT)) {
279 __ CmpInstanceType(map, FIRST_NONSTRING_TYPE); 291 // spec object -> true.
280 __ j(above_equal, &not_string, Label::kNear); 292 Label not_js_object;
281 __ cmp(FieldOperand(eax, String::kLengthOffset), Immediate(0)); 293 __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE);
282 __ j(zero, &false_result, Label::kNear); 294 __ j(below, &not_js_object, Label::kNear);
283 __ jmp(&true_result, Label::kNear); 295 __ Set(tos_, Immediate(1));
296 __ ret(1 * kPointerSize);
297 __ bind(&not_js_object);
298 } else if (types_.Contains(INTERNAL_OBJECT)) {
299 // We've seen a spec object for the first time -> patch.
300 __ CmpInstanceType(map, FIRST_SPEC_OBJECT_TYPE);
301 __ j(above_equal, &patch, Label::kNear);
302 }
284 303
285 __ bind(&not_string); 304 if (types_.Contains(STRING)) {
286 // HeapNumber -> false iff +0, -0, or NaN. 305 // String value -> false iff empty.
287 __ cmp(map, factory->heap_number_map()); 306 Label not_string;
288 __ j(not_equal, &true_result, Label::kNear); 307 __ CmpInstanceType(map, FIRST_NONSTRING_TYPE);
289 __ fldz(); 308 __ j(above_equal, &not_string, Label::kNear);
290 __ fld_d(FieldOperand(eax, HeapNumber::kValueOffset)); 309 __ mov(tos_, FieldOperand(argument, String::kLengthOffset));
291 __ FCmp(); 310 __ ret(1 * kPointerSize); // the string length is OK as the return value
292 __ j(zero, &false_result, Label::kNear); 311 __ bind(&not_string);
293 // Fall through to |true_result|. 312 } else if (types_.Contains(INTERNAL_OBJECT)) {
313 // We've seen a string for the first time -> patch
314 __ CmpInstanceType(map, FIRST_NONSTRING_TYPE);
315 __ j(below, &patch, Label::kNear);
316 }
294 317
295 // Return 1/0 for true/false in tos_. 318 if (types_.Contains(HEAP_NUMBER)) {
296 __ bind(&true_result); 319 // heap number -> false iff +0, -0, or NaN.
297 __ mov(tos_, 1); 320 Label not_heap_number, false_result;
298 __ ret(1 * kPointerSize); 321 __ cmp(map, factory->heap_number_map());
299 __ bind(&false_result); 322 __ j(not_equal, &not_heap_number, Label::kNear);
300 __ mov(tos_, 0); 323 __ fldz();
301 __ ret(1 * kPointerSize); 324 __ fld_d(FieldOperand(argument, HeapNumber::kValueOffset));
325 __ FCmp();
326 __ j(zero, &false_result, Label::kNear);
327 __ Set(tos_, Immediate(1));
328 __ ret(1 * kPointerSize);
329 __ bind(&false_result);
330 __ Set(tos_, Immediate(0));
331 __ ret(1 * kPointerSize);
332 __ bind(&not_heap_number);
333 } else if (types_.Contains(INTERNAL_OBJECT)) {
334 // We've seen a heap number for the first time -> patch
335 __ cmp(map, factory->heap_number_map());
336 __ j(equal, &patch, Label::kNear);
337 }
338
339 if (types_.Contains(INTERNAL_OBJECT)) {
340 // internal objects -> true
341 __ Set(tos_, Immediate(1));
342 __ ret(1 * kPointerSize);
343 }
344
345 if (!types_.IsAll()) {
346 __ bind(&patch);
347 GenerateTypeTransition(masm);
348 }
302 } 349 }
303 350
304 351
305 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) { 352 void StoreBufferOverflowStub::Generate(MacroAssembler* masm) {
306 // We don't allow a GC during a store buffer overflow so there is no need to 353 // We don't allow a GC during a store buffer overflow so there is no need to
307 // store the registers in any particular way, but we do have to store and 354 // store the registers in any particular way, but we do have to store and
308 // restore them. 355 // restore them.
309 __ pushad(); 356 __ pushad();
310 if (save_doubles_ == kSaveFPRegs) { 357 if (save_doubles_ == kSaveFPRegs) {
311 CpuFeatures::Scope scope(SSE2); 358 CpuFeatures::Scope scope(SSE2);
(...skipping 16 matching lines...) Expand all
328 XMMRegister reg = XMMRegister::from_code(i); 375 XMMRegister reg = XMMRegister::from_code(i);
329 __ movdbl(reg, Operand(esp, i * kDoubleSize)); 376 __ movdbl(reg, Operand(esp, i * kDoubleSize));
330 } 377 }
331 __ add(Operand(esp), Immediate(kDoubleSize * XMMRegister::kNumRegisters)); 378 __ add(Operand(esp), Immediate(kDoubleSize * XMMRegister::kNumRegisters));
332 } 379 }
333 __ popad(); 380 __ popad();
334 __ ret(0); 381 __ ret(0);
335 } 382 }
336 383
337 384
385 void ToBooleanStub::CheckOddball(MacroAssembler* masm,
386 Type type,
387 Heap::RootListIndex value,
388 bool result,
389 Label* patch) {
390 const Register argument = eax;
391 if (types_.Contains(type)) {
392 // If we see an expected oddball, return its ToBoolean value tos_.
393 Label different_value;
394 __ CompareRoot(argument, value);
395 __ j(not_equal, &different_value, Label::kNear);
396 __ Set(tos_, Immediate(result ? 1 : 0));
397 __ ret(1 * kPointerSize);
398 __ bind(&different_value);
399 } else if (types_.Contains(INTERNAL_OBJECT)) {
400 // If we see an unexpected oddball and handle internal objects, we must
401 // patch because the code for internal objects doesn't handle it explictly.
402 __ CompareRoot(argument, value);
403 __ j(equal, patch);
404 }
405 }
406
407
408 void ToBooleanStub::GenerateTypeTransition(MacroAssembler* masm) {
409 __ pop(ecx); // Get return address, operand is now on top of stack.
410 __ push(Immediate(Smi::FromInt(tos_.code())));
411 __ push(Immediate(Smi::FromInt(types_.ToByte())));
412 __ push(ecx); // Push return address.
413 // Patch the caller to an appropriate specialized stub and return the
414 // operation result to the caller of the stub.
415 __ TailCallExternalReference(
416 ExternalReference(IC_Utility(IC::kToBoolean_Patch), masm->isolate()),
417 3,
418 1);
419 }
420
421
338 class FloatingPointHelper : public AllStatic { 422 class FloatingPointHelper : public AllStatic {
339 public: 423 public:
340 enum ArgLocation { 424 enum ArgLocation {
341 ARGS_ON_STACK, 425 ARGS_ON_STACK,
342 ARGS_IN_REGISTERS 426 ARGS_IN_REGISTERS
343 }; 427 };
344 428
345 // Code pattern for loading a floating point value. Input value must 429 // Code pattern for loading a floating point value. Input value must
346 // be either a smi or a heap number object (fp value). Requirements: 430 // be either a smi or a heap number object (fp value). Requirements:
347 // operand in register number. Returns operand as floating point number 431 // operand in register number. Returns operand as floating point number
(...skipping 189 matching lines...) Expand 10 before | Expand all | Expand 10 after
537 __ j(greater, &negative, Label::kNear); 621 __ j(greater, &negative, Label::kNear);
538 __ mov(ecx, scratch2); 622 __ mov(ecx, scratch2);
539 __ jmp(&done, Label::kNear); 623 __ jmp(&done, Label::kNear);
540 __ bind(&negative); 624 __ bind(&negative);
541 __ sub(ecx, Operand(scratch2)); 625 __ sub(ecx, Operand(scratch2));
542 __ bind(&done); 626 __ bind(&done);
543 } 627 }
544 } 628 }
545 629
546 630
547 const char* UnaryOpStub::GetName() { 631 void UnaryOpStub::PrintName(StringStream* stream) {
548 if (name_ != NULL) return name_;
549 const int kMaxNameLength = 100;
550 name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
551 kMaxNameLength);
552 if (name_ == NULL) return "OOM";
553 const char* op_name = Token::Name(op_); 632 const char* op_name = Token::Name(op_);
554 const char* overwrite_name = NULL; // Make g++ happy. 633 const char* overwrite_name = NULL; // Make g++ happy.
555 switch (mode_) { 634 switch (mode_) {
556 case UNARY_NO_OVERWRITE: overwrite_name = "Alloc"; break; 635 case UNARY_NO_OVERWRITE: overwrite_name = "Alloc"; break;
557 case UNARY_OVERWRITE: overwrite_name = "Overwrite"; break; 636 case UNARY_OVERWRITE: overwrite_name = "Overwrite"; break;
558 } 637 }
559 638 stream->Add("UnaryOpStub_%s_%s_%s",
560 OS::SNPrintF(Vector<char>(name_, kMaxNameLength), 639 op_name,
561 "UnaryOpStub_%s_%s_%s", 640 overwrite_name,
562 op_name, 641 UnaryOpIC::GetName(operand_type_));
563 overwrite_name,
564 UnaryOpIC::GetName(operand_type_));
565 return name_;
566 } 642 }
567 643
568 644
569 // TODO(svenpanne): Use virtual functions instead of switch. 645 // TODO(svenpanne): Use virtual functions instead of switch.
570 void UnaryOpStub::Generate(MacroAssembler* masm) { 646 void UnaryOpStub::Generate(MacroAssembler* masm) {
571 switch (operand_type_) { 647 switch (operand_type_) {
572 case UnaryOpIC::UNINITIALIZED: 648 case UnaryOpIC::UNINITIALIZED:
573 GenerateTypeTransition(masm); 649 GenerateTypeTransition(masm);
574 break; 650 break;
575 case UnaryOpIC::SMI: 651 case UnaryOpIC::SMI:
(...skipping 364 matching lines...) Expand 10 before | Expand all | Expand 10 after
940 break; 1016 break;
941 case BinaryOpIC::GENERIC: 1017 case BinaryOpIC::GENERIC:
942 GenerateGeneric(masm); 1018 GenerateGeneric(masm);
943 break; 1019 break;
944 default: 1020 default:
945 UNREACHABLE(); 1021 UNREACHABLE();
946 } 1022 }
947 } 1023 }
948 1024
949 1025
950 const char* BinaryOpStub::GetName() { 1026 void BinaryOpStub::PrintName(StringStream* stream) {
951 if (name_ != NULL) return name_;
952 const int kMaxNameLength = 100;
953 name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
954 kMaxNameLength);
955 if (name_ == NULL) return "OOM";
956 const char* op_name = Token::Name(op_); 1027 const char* op_name = Token::Name(op_);
957 const char* overwrite_name; 1028 const char* overwrite_name;
958 switch (mode_) { 1029 switch (mode_) {
959 case NO_OVERWRITE: overwrite_name = "Alloc"; break; 1030 case NO_OVERWRITE: overwrite_name = "Alloc"; break;
960 case OVERWRITE_RIGHT: overwrite_name = "OverwriteRight"; break; 1031 case OVERWRITE_RIGHT: overwrite_name = "OverwriteRight"; break;
961 case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break; 1032 case OVERWRITE_LEFT: overwrite_name = "OverwriteLeft"; break;
962 default: overwrite_name = "UnknownOverwrite"; break; 1033 default: overwrite_name = "UnknownOverwrite"; break;
963 } 1034 }
964 1035 stream->Add("BinaryOpStub_%s_%s_%s",
965 OS::SNPrintF(Vector<char>(name_, kMaxNameLength), 1036 op_name,
966 "BinaryOpStub_%s_%s_%s", 1037 overwrite_name,
967 op_name, 1038 BinaryOpIC::GetName(operands_type_));
968 overwrite_name,
969 BinaryOpIC::GetName(operands_type_));
970 return name_;
971 } 1039 }
972 1040
973 1041
974 void BinaryOpStub::GenerateSmiCode( 1042 void BinaryOpStub::GenerateSmiCode(
975 MacroAssembler* masm, 1043 MacroAssembler* masm,
976 Label* slow, 1044 Label* slow,
977 SmiCodeGenerateHeapNumberResults allow_heapnumber_results) { 1045 SmiCodeGenerateHeapNumberResults allow_heapnumber_results) {
978 // 1. Move arguments into edx, eax except for DIV and MOD, which need the 1046 // 1. Move arguments into edx, eax except for DIV and MOD, which need the
979 // dividend in eax and edx free for the division. Use eax, ebx for those. 1047 // dividend in eax and edx free for the division. Use eax, ebx for those.
980 Comment load_comment(masm, "-- Load arguments"); 1048 Comment load_comment(masm, "-- Load arguments");
(...skipping 3225 matching lines...) Expand 10 before | Expand all | Expand 10 after
4206 // Slow-case: Non-function called. 4274 // Slow-case: Non-function called.
4207 __ bind(&slow); 4275 __ bind(&slow);
4208 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead 4276 // CALL_NON_FUNCTION expects the non-function callee as receiver (instead
4209 // of the original receiver from the call site). 4277 // of the original receiver from the call site).
4210 __ mov(Operand(esp, (argc_ + 1) * kPointerSize), edi); 4278 __ mov(Operand(esp, (argc_ + 1) * kPointerSize), edi);
4211 __ Set(eax, Immediate(argc_)); 4279 __ Set(eax, Immediate(argc_));
4212 __ Set(ebx, Immediate(0)); 4280 __ Set(ebx, Immediate(0));
4213 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION); 4281 __ GetBuiltinEntry(edx, Builtins::CALL_NON_FUNCTION);
4214 Handle<Code> adaptor = 4282 Handle<Code> adaptor =
4215 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline(); 4283 masm->isolate()->builtins()->ArgumentsAdaptorTrampoline();
4284 __ SetCallKind(ecx, CALL_AS_METHOD);
4216 __ jmp(adaptor, RelocInfo::CODE_TARGET); 4285 __ jmp(adaptor, RelocInfo::CODE_TARGET);
4217 } 4286 }
4218 4287
4219 4288
4220 bool CEntryStub::NeedsImmovableCode() { 4289 bool CEntryStub::NeedsImmovableCode() {
4221 return false; 4290 return false;
4222 } 4291 }
4223 4292
4224 4293
4225 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) { 4294 void CEntryStub::GenerateThrowTOS(MacroAssembler* masm) {
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after
4412 __ bind(&throw_termination_exception); 4481 __ bind(&throw_termination_exception);
4413 GenerateThrowUncatchable(masm, TERMINATION); 4482 GenerateThrowUncatchable(masm, TERMINATION);
4414 4483
4415 __ bind(&throw_normal_exception); 4484 __ bind(&throw_normal_exception);
4416 GenerateThrowTOS(masm); 4485 GenerateThrowTOS(masm);
4417 } 4486 }
4418 4487
4419 4488
4420 void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) { 4489 void JSEntryStub::GenerateBody(MacroAssembler* masm, bool is_construct) {
4421 Label invoke, exit; 4490 Label invoke, exit;
4422 #ifdef ENABLE_LOGGING_AND_PROFILING
4423 Label not_outermost_js, not_outermost_js_2; 4491 Label not_outermost_js, not_outermost_js_2;
4424 #endif
4425 4492
4426 // Setup frame. 4493 // Setup frame.
4427 __ push(ebp); 4494 __ push(ebp);
4428 __ mov(ebp, Operand(esp)); 4495 __ mov(ebp, Operand(esp));
4429 4496
4430 // Push marker in two places. 4497 // Push marker in two places.
4431 int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY; 4498 int marker = is_construct ? StackFrame::ENTRY_CONSTRUCT : StackFrame::ENTRY;
4432 __ push(Immediate(Smi::FromInt(marker))); // context slot 4499 __ push(Immediate(Smi::FromInt(marker))); // context slot
4433 __ push(Immediate(Smi::FromInt(marker))); // function slot 4500 __ push(Immediate(Smi::FromInt(marker))); // function slot
4434 // Save callee-saved registers (C calling conventions). 4501 // Save callee-saved registers (C calling conventions).
4435 __ push(edi); 4502 __ push(edi);
4436 __ push(esi); 4503 __ push(esi);
4437 __ push(ebx); 4504 __ push(ebx);
4438 4505
4439 // Save copies of the top frame descriptor on the stack. 4506 // Save copies of the top frame descriptor on the stack.
4440 ExternalReference c_entry_fp(Isolate::k_c_entry_fp_address, masm->isolate()); 4507 ExternalReference c_entry_fp(Isolate::k_c_entry_fp_address, masm->isolate());
4441 __ push(Operand::StaticVariable(c_entry_fp)); 4508 __ push(Operand::StaticVariable(c_entry_fp));
4442 4509
4443 #ifdef ENABLE_LOGGING_AND_PROFILING
4444 // If this is the outermost JS call, set js_entry_sp value. 4510 // If this is the outermost JS call, set js_entry_sp value.
4445 ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address, 4511 ExternalReference js_entry_sp(Isolate::k_js_entry_sp_address,
4446 masm->isolate()); 4512 masm->isolate());
4447 __ cmp(Operand::StaticVariable(js_entry_sp), Immediate(0)); 4513 __ cmp(Operand::StaticVariable(js_entry_sp), Immediate(0));
4448 __ j(not_equal, &not_outermost_js); 4514 __ j(not_equal, &not_outermost_js);
4449 __ mov(Operand::StaticVariable(js_entry_sp), ebp); 4515 __ mov(Operand::StaticVariable(js_entry_sp), ebp);
4450 __ push(Immediate(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME))); 4516 __ push(Immediate(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME)));
4451 Label cont; 4517 Label cont;
4452 __ jmp(&cont); 4518 __ jmp(&cont);
4453 __ bind(&not_outermost_js); 4519 __ bind(&not_outermost_js);
4454 __ push(Immediate(Smi::FromInt(StackFrame::INNER_JSENTRY_FRAME))); 4520 __ push(Immediate(Smi::FromInt(StackFrame::INNER_JSENTRY_FRAME)));
4455 __ bind(&cont); 4521 __ bind(&cont);
4456 #endif
4457 4522
4458 // Call a faked try-block that does the invoke. 4523 // Call a faked try-block that does the invoke.
4459 __ call(&invoke); 4524 __ call(&invoke);
4460 4525
4461 // Caught exception: Store result (exception) in the pending 4526 // Caught exception: Store result (exception) in the pending
4462 // exception field in the JSEnv and return a failure sentinel. 4527 // exception field in the JSEnv and return a failure sentinel.
4463 ExternalReference pending_exception(Isolate::k_pending_exception_address, 4528 ExternalReference pending_exception(Isolate::k_pending_exception_address,
4464 masm->isolate()); 4529 masm->isolate());
4465 __ mov(Operand::StaticVariable(pending_exception), eax); 4530 __ mov(Operand::StaticVariable(pending_exception), eax);
4466 __ mov(eax, reinterpret_cast<int32_t>(Failure::Exception())); 4531 __ mov(eax, reinterpret_cast<int32_t>(Failure::Exception()));
(...skipping 27 matching lines...) Expand all
4494 __ mov(edx, Immediate(entry)); 4559 __ mov(edx, Immediate(entry));
4495 } 4560 }
4496 __ mov(edx, Operand(edx, 0)); // deref address 4561 __ mov(edx, Operand(edx, 0)); // deref address
4497 __ lea(edx, FieldOperand(edx, Code::kHeaderSize)); 4562 __ lea(edx, FieldOperand(edx, Code::kHeaderSize));
4498 __ call(Operand(edx)); 4563 __ call(Operand(edx));
4499 4564
4500 // Unlink this frame from the handler chain. 4565 // Unlink this frame from the handler chain.
4501 __ PopTryHandler(); 4566 __ PopTryHandler();
4502 4567
4503 __ bind(&exit); 4568 __ bind(&exit);
4504 #ifdef ENABLE_LOGGING_AND_PROFILING
4505 // Check if the current stack frame is marked as the outermost JS frame. 4569 // Check if the current stack frame is marked as the outermost JS frame.
4506 __ pop(ebx); 4570 __ pop(ebx);
4507 __ cmp(Operand(ebx), 4571 __ cmp(Operand(ebx),
4508 Immediate(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME))); 4572 Immediate(Smi::FromInt(StackFrame::OUTERMOST_JSENTRY_FRAME)));
4509 __ j(not_equal, &not_outermost_js_2); 4573 __ j(not_equal, &not_outermost_js_2);
4510 __ mov(Operand::StaticVariable(js_entry_sp), Immediate(0)); 4574 __ mov(Operand::StaticVariable(js_entry_sp), Immediate(0));
4511 __ bind(&not_outermost_js_2); 4575 __ bind(&not_outermost_js_2);
4512 #endif
4513 4576
4514 // Restore the top frame descriptor from the stack. 4577 // Restore the top frame descriptor from the stack.
4515 __ pop(Operand::StaticVariable(ExternalReference( 4578 __ pop(Operand::StaticVariable(ExternalReference(
4516 Isolate::k_c_entry_fp_address, 4579 Isolate::k_c_entry_fp_address,
4517 masm->isolate()))); 4580 masm->isolate())));
4518 4581
4519 // Restore callee-saved registers (C calling conventions). 4582 // Restore callee-saved registers (C calling conventions).
4520 __ pop(ebx); 4583 __ pop(ebx);
4521 __ pop(esi); 4584 __ pop(esi);
4522 __ pop(edi); 4585 __ pop(edi);
(...skipping 241 matching lines...) Expand 10 before | Expand all | Expand 10 after
4764 | RegisterField::encode(false) // lhs_ and rhs_ are not used 4827 | RegisterField::encode(false) // lhs_ and rhs_ are not used
4765 | StrictField::encode(strict_) 4828 | StrictField::encode(strict_)
4766 | NeverNanNanField::encode(cc_ == equal ? never_nan_nan_ : false) 4829 | NeverNanNanField::encode(cc_ == equal ? never_nan_nan_ : false)
4767 | IncludeNumberCompareField::encode(include_number_compare_) 4830 | IncludeNumberCompareField::encode(include_number_compare_)
4768 | IncludeSmiCompareField::encode(include_smi_compare_); 4831 | IncludeSmiCompareField::encode(include_smi_compare_);
4769 } 4832 }
4770 4833
4771 4834
4772 // Unfortunately you have to run without snapshots to see most of these 4835 // Unfortunately you have to run without snapshots to see most of these
4773 // names in the profile since most compare stubs end up in the snapshot. 4836 // names in the profile since most compare stubs end up in the snapshot.
4774 const char* CompareStub::GetName() { 4837 void CompareStub::PrintName(StringStream* stream) {
4775 ASSERT(lhs_.is(no_reg) && rhs_.is(no_reg)); 4838 ASSERT(lhs_.is(no_reg) && rhs_.is(no_reg));
4776
4777 if (name_ != NULL) return name_;
4778 const int kMaxNameLength = 100;
4779 name_ = Isolate::Current()->bootstrapper()->AllocateAutoDeletedArray(
4780 kMaxNameLength);
4781 if (name_ == NULL) return "OOM";
4782
4783 const char* cc_name; 4839 const char* cc_name;
4784 switch (cc_) { 4840 switch (cc_) {
4785 case less: cc_name = "LT"; break; 4841 case less: cc_name = "LT"; break;
4786 case greater: cc_name = "GT"; break; 4842 case greater: cc_name = "GT"; break;
4787 case less_equal: cc_name = "LE"; break; 4843 case less_equal: cc_name = "LE"; break;
4788 case greater_equal: cc_name = "GE"; break; 4844 case greater_equal: cc_name = "GE"; break;
4789 case equal: cc_name = "EQ"; break; 4845 case equal: cc_name = "EQ"; break;
4790 case not_equal: cc_name = "NE"; break; 4846 case not_equal: cc_name = "NE"; break;
4791 default: cc_name = "UnknownCondition"; break; 4847 default: cc_name = "UnknownCondition"; break;
4792 } 4848 }
4793 4849 bool is_equality = cc_ == equal || cc_ == not_equal;
4794 const char* strict_name = ""; 4850 stream->Add("CompareStub_%s", cc_name);
4795 if (strict_ && (cc_ == equal || cc_ == not_equal)) { 4851 if (strict_ && is_equality) stream->Add("_STRICT");
4796 strict_name = "_STRICT"; 4852 if (never_nan_nan_ && is_equality) stream->Add("_NO_NAN");
4797 } 4853 if (!include_number_compare_) stream->Add("_NO_NUMBER");
4798 4854 if (!include_smi_compare_) stream->Add("_NO_SMI");
4799 const char* never_nan_nan_name = "";
4800 if (never_nan_nan_ && (cc_ == equal || cc_ == not_equal)) {
4801 never_nan_nan_name = "_NO_NAN";
4802 }
4803
4804 const char* include_number_compare_name = "";
4805 if (!include_number_compare_) {
4806 include_number_compare_name = "_NO_NUMBER";
4807 }
4808
4809 const char* include_smi_compare_name = "";
4810 if (!include_smi_compare_) {
4811 include_smi_compare_name = "_NO_SMI";
4812 }
4813
4814 OS::SNPrintF(Vector<char>(name_, kMaxNameLength),
4815 "CompareStub_%s%s%s%s%s",
4816 cc_name,
4817 strict_name,
4818 never_nan_nan_name,
4819 include_number_compare_name,
4820 include_smi_compare_name);
4821 return name_;
4822 } 4855 }
4823 4856
4824 4857
4825 // ------------------------------------------------------------------------- 4858 // -------------------------------------------------------------------------
4826 // StringCharCodeAtGenerator 4859 // StringCharCodeAtGenerator
4827 4860
4828 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) { 4861 void StringCharCodeAtGenerator::GenerateFast(MacroAssembler* masm) {
4829 Label flat_string; 4862 Label flat_string;
4830 Label ascii_string; 4863 Label ascii_string;
4831 Label got_char_code; 4864 Label got_char_code;
(...skipping 1736 matching lines...) Expand 10 before | Expand all | Expand 10 after
6568 6601
6569 // Fall through when we need to inform the incremental marker. 6602 // Fall through when we need to inform the incremental marker.
6570 } 6603 }
6571 6604
6572 6605
6573 #undef __ 6606 #undef __
6574 6607
6575 } } // namespace v8::internal 6608 } } // namespace v8::internal
6576 6609
6577 #endif // V8_TARGET_ARCH_IA32 6610 #endif // V8_TARGET_ARCH_IA32
OLDNEW
« no previous file with comments | « src/ia32/code-stubs-ia32.h ('k') | src/ia32/codegen-ia32.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698